package com.link.base.base.order.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.link.base.base.accnt.dao.mybatis.mapper.AccountMapper;
import com.link.base.base.accnt.model.Account;
import com.link.base.base.accnt.service.AccountService;
import com.link.base.base.approval.model.FlowType;
import com.link.base.base.approval.service.FlowService;
import com.link.base.base.common.model.Attachment;
import com.link.base.base.common.service.AttachmentService;
import com.link.base.base.coupons.dao.mybatis.mapper.CollectRecordMapper;
import com.link.base.base.coupons.dao.mybatis.mapper.CouponsMapper;
import com.link.base.base.coupons.model.CollectRecord;
import com.link.base.base.coupons.model.Coupons;
import com.link.base.base.coupons.service.CollectRecordService;
import com.link.base.base.coupons.service.CouponsService;
import com.link.base.base.delivery.model.DeliveryDetails;
import com.link.base.base.delivery.service.DeliveryDetailsService;
import com.link.base.base.fund.model.DealerAccount;
import com.link.base.base.fund.model.DealerTransactionDetail;
import com.link.base.base.fund.service.DealerAccountService;
import com.link.base.base.fund.service.DealerTransactionDetailService;
import com.link.base.base.invloc.model.Invloc;
import com.link.base.base.invloc.service.InvlocService;
import com.link.base.base.invtxn.model.Invtxn;
import com.link.base.base.invtxn.service.InvtxnService;
import com.link.base.base.logcode.model.LogCode;
import com.link.base.base.logcode.service.LogCodeService;
import com.link.base.base.message.push.service.PushService;
import com.link.base.base.order.dao.mybatis.mapper.PayRecordMapper;
import com.link.base.base.order.dao.mybatis.mapper.SaleOrderMapper;
import com.link.base.base.order.model.*;
import com.link.base.base.orderpayset.model.OrderPaySet;
import com.link.base.base.orderpayset.service.OrderPaySetService;
import com.link.base.base.orgnization.model.Orgnization;
import com.link.base.base.orgnization.service.OrgnizationService;
import com.link.base.base.policy.service.PolicyService;
import com.link.base.base.product.dao.mybatis.mapper.ProductMapper;
import com.link.base.base.product.model.PriceListItem;
import com.link.base.base.product.model.Product;
import com.link.base.base.product.model.ShopCart;
import com.link.base.base.product.service.PriceListItemService;
import com.link.base.base.product.service.ProductService;
import com.link.base.base.product.service.ShopCartService;
import com.link.base.base.report.dao.mybatis.mapper.GuideReportMapper;
import com.link.base.base.report.model.GuideReport;
import com.link.base.base.salecategory.model.SaleCategory;
import com.link.base.base.salecategory.service.SaleCategoryService;
import com.link.base.base.salestarget.dao.mybatis.mapper.SalesTargetMapper;
import com.link.base.base.salestarget.model.SalesTarget;
import com.link.base.loyalty.member.model.Member;
import com.link.base.loyalty.transaction.model.Transaction;
import com.link.base.microinterface.interaction.microservice.InteractionClient;
import com.link.base.microinterface.microservice.CouponsClient;
import com.link.base.microinterface.microservice.MemberClient;
import com.link.base.microinterface.microservice.TransactionClient;
import com.link.base.microinterface.microservice.model.LytMember;
import com.link.base.user.model.CoreUser;
import com.link.core.basic.dao.BasicDaoException;
import com.link.core.basic.dao.KeyGenerateDao;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.model.CallParam;
import com.link.core.basic.query.Filter;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.basic.service.ServiceException;
import com.link.core.basic.service.snowflake.GenerateCodeSingleton;
import com.link.core.basic.thread.LinkThreadPoolExecutor;
import com.link.core.cllog.LCLogger;
import com.link.core.util.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author unknown
 * @date unknown
 * @comments 定单服务
 */
@Service
public class SaleOrderServiceImpl extends BasicServiceImpl<SaleOrder> implements SaleOrderService {

    @Resource
    private SaleOrderMapper saleOrderMapper;
    @Resource
    private FlowService flowService;
    @Resource
    private OrderPolicyService orderPolicyService;
    @Resource
    private PushService pushService;
    @Resource
    private SaleOrderItemService saleOrderItemService;
    @Resource
    private KeyGenerateService keyGenerateService;
    @Resource
    private AccountService accountService;
    @Resource
    private PriceListItemService priceListItemService;

    @Resource
    private MemberClient memberClient;

    @Resource
    private LogCodeService logCodeService;

    @Resource
    private CouponsClient couponsClient;

    /**
     * 可售品类
     */
    @Resource
    private SaleCategoryService saleCategoryService;
    /**
     * 资金账户头
     */
    @Resource
    private DealerAccountService dealerAccountService;
    @Resource
    private DealerTransactionDetailService dealerTransactionDetailService;
    /**
     * 订单参数对象
     */
    @Resource
    private OrderPaySetService orderPaySetService;
    /**
     * 政策
     */
    @Resource
    private PolicyService policyService;
    @Resource
    private OrgnizationService orgnizationService;
    @Resource
    private InvtxnService invtxnService;
    @Resource
    private InvlocService invlocService;
    @Resource
    private ProductService productService;

    @Resource
    private PayRecordService payRecordService;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private GuideReportMapper guideReportMapper;

    @Resource
    private SalesTargetMapper salesTargetMapper;

    @Resource
    private ShopCartService shopCartService;

    @Resource
    private PayRecordMapper payRecordMapper;

    @Resource
    private CouponsMapper couponsMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private CollectRecordMapper collectRecordMapper;

    @Resource
    private CollectRecordService collectRecordService;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private DeliveryDetailsService deliveryDetailsService;

    @Resource
    private CouponsService couponsService;


    @Resource
    private TransactionClient transactionClient;

    @Resource
    private KeyGenerateDao keyGenerateDao;

    @Resource
    private LinkThreadPoolExecutor linkThreadPoolExecutor;

    @Resource
    private InteractionClient interactionClient;

    @Resource
    private AttachmentService attachmentService;

    //使用GenerateCodeSingleton获取订单编号
    GenerateCodeSingleton generateCodeSingleton = GenerateCodeSingleton.getInstance();

    @Override
    public BasicMapper<SaleOrder> getBasicMapper() {
        return saleOrderMapper;
    }

    @Override
    public void beforUpdate(SaleOrder entity) throws Exception {
        super.beforUpdate(entity);
        SaleOrder validateObj = queryById(entity);
        if (validateObj == null) {
            //当没有查询到已有记录的时候。直接返回。表示当前是直接提交的。
            return;
        }
        String newStr = "New";
        String submitted = "Submitted";
        String rejected = "Rejected";
        String closed = "Closed";
        if (!newStr.equals(validateObj.getStatusLovType()) && !submitted.equals(validateObj.getStatusLovType())
                && !rejected.equals(validateObj.getStatusLovType()) && !closed.equals(validateObj.getStatusLovType())) {
            throw new ServiceException("ORDER-027");
        }

        //更新之前，先校验订单信息是否被修改过，如果被修改，则报错
        //校验产品价格
        //checkOrderProductAndPrice(entity);
    }

    @Override
    public void beforInsert(SaleOrder entity) throws Exception {
        super.beforInsert(entity);
        if (StringUtils.isBlank(entity.getOrderType())) {
            throw new ServiceException("ORDER-017");
        }

        if (entity.getAcctId() == null) {
            throw new ServiceException("PUBLIC-026");
        }
        if (StringUtils.isBlank(entity.getOrderNo())) {
            entity.setOrderNo(generateCodeSingleton.getOrderCodeStr());
        }
        if (StringUtils.isBlank(entity.getStatus())) {
            entity.setStatus("New");
        }

    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void commentsUpdate(SaleOrder record) throws ServiceException {
        try {
            saleOrderMapper.commentsUpdate(record);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public Double countTotalCash(SaleOrder record) throws ServiceException {
        Double rs = 0.0;
        try {
            rs = saleOrderMapper.countTotalCash(record);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new RuntimeException(e.getMessage());
        }
        return rs;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void cancelSaleOrderUpdate(SaleOrder record) throws ServiceException {
        try {
            SaleOrder validateObj = queryById(record);
            String newStr = "New";
            String submitted = "Submitted";
            if (!newStr.equals(validateObj.getStatusLovType()) && !submitted.equals(validateObj.getStatusLovType())) {
                throw new ServiceException("ORDER-028");
            }
            saleOrderMapper.cancelSaleOrderUpdate(record);
            pushService.sampleMessageOnlyUser("订单【" + validateObj.getOrderNo() + "】已经取消！", validateObj.getCreatedBy());
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public SaleOrder querySaleOrderTotalAmount(SaleOrder record) throws ServiceException {
        SaleOrder saleOrder = new SaleOrder();
        try {
            saleOrder = saleOrderMapper.querySaleOrderTotalAmount(record);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException(e.getMessage());
        }
        return saleOrder;
    }

    @Override
    public void orderAcctIdUpdate(SaleOrder record) throws ServiceException {
        try {
            saleOrderMapper.orderAcctIdUpdate(record);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void orderCommitUpdate(SaleOrder record, Long selectUserId) throws Exception {
        SaleOrder validateObj = queryById(record);
        String newStr = "New";
        String rejected = "Rejected";
        if (!StringUtils.equals(validateObj.getStatus(), newStr) && !StringUtils.equals(validateObj.getStatus(), rejected)) {
            throw new ServiceException("ORDER-029");
        }
        record.setStatus("Submitted");
        saleOrderMapper.orderCommitUpdate(record);
        flowService.createFlow(record.getId(), FlowType.ORDER_SUBMIT, selectUserId, "订单编号:" + validateObj.getOrderNo(), Long.parseLong(""), "");
    }

    @Override
    public void sendComplete(SaleOrder record) throws Exception {
        if (record.getId() == null || "".equals(record.getId())) {
            throw new ServiceException("ORDER-018");
        }
        CallParam callParam = new CallParam();
        callParam.setParam1(record.getId());
        callParam.setParam2(String.valueOf(UserUtil.getUser().getId()));
        saleOrderMapper.callOrderComplete(callParam);
        String ok = "OK";
        if (!ok.equals(callParam.getReturnStatus())) {
            throw new ServiceException(callParam.getMsgData());
        }

    }

    @Override
    public void approvalUpdateOrderStatus(Long objectId, String param1, String param2, String param3, String param4,
                                          String param5) throws Exception {
        SaleOrder queryOrder = new SaleOrder();
        queryOrder.setId(objectId);
        SaleOrder saleOrder = queryById(queryOrder);
        if (saleOrder == null) {
            throw new ServiceException("ORDER-030");
        }
        //审批拒绝
        String rejected = "Rejected";
        if (rejected.equals(param1)) {
            SaleOrder record = new SaleOrder();
            record.setId(objectId);
            record.setStatus(param1);
            saleOrderMapper.orderStatusUpdate(record);
        }
        //审批通过
        String approved = "Approved";
        if (approved.equals(param1)) {
            SaleOrder record = new SaleOrder();
            record.setId(objectId);
            record.setStatus(param1);
            saleOrderMapper.orderStatusUpdate(record);
        }
    }

    @Override
    public void approvalUpdateOrderInfo(Long objectId, String attr1, String attr2, String attr3, String attr4,
                                        String attr5, String attr6, String attr7, String attr8, String attr9, String attr10) throws Exception {
        String yFlag = "Y";
        String nFalg = "N";
        if (!(yFlag.equalsIgnoreCase(attr1) || nFalg.equalsIgnoreCase(attr1))) {
            throw new ServiceException("ORDER-031");
        }
    }

    @Override
    public SaleOrder queryOneById(Long id) throws Exception {
        SaleOrder example = new SaleOrder();
        example.setId(id);
        return queryById(example);
    }

    @Override
    public void orderApprovedUpdate(SaleOrder order) throws Exception {
        if (order.getId() == null) {
            throw new ServiceException("ORDER-030");
        }
        order = queryById(order);
        if (order == null) {
            throw new ServiceException("ORDER-030");
        }
        String submitted = "Submitted";
        if (submitted.equals(order.getStatus())) {
            order.setStatus("Approved");
            saleOrderMapper.orderStatusUpdate(order);
        } else {
            throw new ServiceException("ORDER-032");
        }
    }

    @Override
    public void orderConfirmSendUpdate(SaleOrder order) throws Exception {
        if (order.getId() == null) {
            throw new ServiceException("ORDER-030");
        }
        order = queryById(order);
        if (order == null) {
            throw new ServiceException("ORDER-030");
        }
        //当为门店订单的时候，订单状态需要是待配送
        String approved = "Approved";
        String undelivered = "Undelivered";
        if (approved.equals(order.getStatus())) {
            // 创建发货订单
            createDeliveryDatailInfo(order);
            order.setStatus("Shipped");
            saleOrderMapper.orderStatusUpdate(order);
        } else if (undelivered.equals(order.getStatus()) && isStoreOrder(order)) {
            order.setStatus("Closed");
            saleOrderMapper.orderStatusUpdate(order);
        } else {

            throw new ServiceException("ORDER-033");
        }
        pushService.sampleMessageOnlyUser("订单【" + order.getOrderNo() + "】已经发货！", order.getCreatedBy());

    }

    /**
     * 创建发货明细信息
     */
    private void createDeliveryDatailInfo(SaleOrder order) throws Exception {

        List<SaleOrderItem> items = saleOrderItemService.querylistByOrderId(order.getId());
        if (CollectionUtils.isEmpty(items)) {
            throw new ServiceException("ORDER-034");
        }
        items.stream().forEach(item -> {
            //
            DeliveryDetails deliveryDetails = new DeliveryDetails();
            //订单id
            deliveryDetails.setOrderId(order.getId());
            deliveryDetails.setOrderItemId(item.getId());
            deliveryDetails.setProdId(item.getProdId());
            deliveryDetails.setDeliveryQty(item.getQty());
            deliveryDetails.setDeliveryUnit(item.getProdUnit());
            deliveryDetails.setDeliveryDate(DateUtil.dateToStr(new Date(), ""));
            try {
                deliveryDetailsService.insert(deliveryDetails);
            } catch (Exception e) {
                throw new ServiceException("ORDER-035");
            }
        });
    }

    /**
     * HuangLJ 2018年07月23日
     *
     * @param order 订单对象
     * @return 返回布尔值
     * @throws Exception 报错
     *                   是否是门店订单
     */
    private Boolean isStoreOrder(SaleOrder order) throws Exception {
        String orderKind = order.getOrderKind();
        return "TerminalOrder".equals(orderKind);
    }

    @Override
    public void paidUpdate(SaleOrder order) throws Exception {
        String flag = "Y";
        if (order.getId() == null) {
            throw new ServiceException("ORDER-030");
        }
        order = queryById(order);
        if (order == null) {
            throw new ServiceException("ORDER-030");
        }
        if (flag.equals(order.getIsPaid())) {
            throw new ServiceException("ORDER-036");
        }
        order.setIsPaid("Y");
        saleOrderMapper.isPaidUpdate(order);
    }

    @Override
    public int arrivedUpdate(SaleOrder record) {
        return saleOrderMapper.arrivedUpdate(record);
    }

    @Override
    public int confirmArrivedUpdate(SaleOrder record) {
        return saleOrderMapper.confirmArrivedUpdate(record);
    }

    @Override
    public void applyPolicy(SaleOrder record) throws Exception {
        orderPolicyService.applyPolicyOne(record);
    }

    @Override
    public int orderStatusUpdate(SaleOrder order) throws Exception {
        return saleOrderMapper.orderStatusUpdate(order);
    }

    @Override
    public void applyPolicyTwo(SaleOrder saleOrder) throws Exception {
        orderPolicyService.applyPolicyTwo(saleOrder);
    }

    @Override
    public List<SaleOrder> querySalesOrderOfDistrictPage(SaleOrder order) throws Exception {
        return saleOrderMapper.querySalesOrderOfDistrictPage(order);
    }

    @Override
    public List<SaleOrder> querySalesOfDistrictPage(SaleOrder order) throws Exception {
        return saleOrderMapper.querySalesOfDistrictPage(order);
    }

    @Override
    public String getSalesOrderReportHtml(List<SaleOrder> list) throws Exception {
        StringBuilder title = new StringBuilder("");
        StringBuilder html1 = new StringBuilder("");
        StringBuilder title1 = new StringBuilder("");
        StringBuilder html2 = new StringBuilder("");
        StringBuilder title2 = new StringBuilder("");
        StringBuilder html3 = new StringBuilder("");
        StringBuilder title3 = new StringBuilder("");
        title.append("<div id=\"showTableDiv\" class=\"showTableDiv\">");
        title.append("<table id=\"SalesOrderDistribution-table\" style=\"height: 100%;\" keyFilterDiv=\"keyFilter\">");
        if (list.size() == 0) {
            title1.append("<tr class=\"titleTr\">");
            html1.append("<tr class=\"conTr\">");
            title1.append("<td width='100px' class=\"titleTd\">" + "无省份" + "</td>");
            html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + "无订单" + "</td>");
            html1.append("</tr>");
            title1.append("</tr>");
        } else {
            int twelve = 12;
            int twentyFour = 24;
            if (list.size() <= twelve) {
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");
            } else if (list.size() > twelve && list.size() <= twentyFour) {
                //换行
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < twelve; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");

                title2.append("<tr class=\"titleTr\">");
                html2.append("<tr class=\"conTr\">");
                for (int n = twelve; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title2.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html2.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html2.append("</tr>");
                title2.append("</tr>");
            } else {
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < twelve; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");

                title2.append("<tr class=\"titleTr\">");
                html2.append("<tr class=\"conTr\">");
                for (int n = twelve; n < twentyFour; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title2.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html2.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html2.append("</tr>");
                title2.append("</tr>");

                title3.append("<tr class=\"titleTr\">");
                html3.append("<tr class=\"conTr\">");
                for (int n = twentyFour; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getTotal());
                    title3.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html3.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html3.append("</tr>");
                title3.append("</tr>");
            }
        }
        html1 = title1.append(html1);
        html2 = title2.append(html2);
        html3 = title3.append(html3);

        StringBuilder html = new StringBuilder("");
        html = title.append(html1.toString() + html2.toString() + html3.toString());
        html.append("</table>");
        html.append("</div>");
        String result = "";
        result = html.toString();
        return result;
    }

    @Override
    public String getSalesReportHtml(List<SaleOrder> list) throws Exception {
        StringBuilder title = new StringBuilder("");
        StringBuilder html1 = new StringBuilder("");
        StringBuilder title1 = new StringBuilder("");
        StringBuilder html2 = new StringBuilder("");
        StringBuilder title2 = new StringBuilder("");
        StringBuilder html3 = new StringBuilder("");
        StringBuilder title3 = new StringBuilder("");
        title.append("<div id=\"showTableDiv\" class=\"showTableDiv\">");
        title.append("<table id=\"SalesDistribution-table\" style=\"height: 100%;\" keyFilterDiv=\"keyFilter\">");
        int twelve = 12;
        int twentyFour = 24;
        if (list.size() == 0) {
            title1.append("<tr class=\"titleTr\">");
            html1.append("<tr class=\"conTr\">");
            title1.append("<td width='100px' class=\"titleTd\">" + "无省份" + "</td>");
            html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + "无销量" + "</td>");
            html1.append("</tr>");
            title1.append("</tr>");
        } else {
            if (list.size() <= twelve) {
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    BigDecimal amountTemp = BigDecimal.valueOf(list.get(n).getOrderTotalAmount() / 10000);
                    amountTemp = amountTemp.setScale(2, BigDecimal.ROUND_HALF_UP);
//                  String amount = nf.format(list.get(n).getOrderTotalAmount());//李杨注释，单位取“万元”，两位小数四舍五入
                    String amount = nf.format(amountTemp);
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");
            } else if (list.size() > twelve && list.size() <= twentyFour) {
                //换行
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < twelve; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getOrderTotalAmount());
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");

                title2.append("<tr class=\"titleTr\">");
                html2.append("<tr class=\"conTr\">");
                for (int n = twelve; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getOrderTotalAmount());
                    title2.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html2.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html2.append("</tr>");
                title2.append("</tr>");
            } else {
                title1.append("<tr class=\"titleTr\">");
                html1.append("<tr class=\"conTr\">");
                for (int n = 0; n < twelve; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getOrderTotalAmount());
                    title1.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html1.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html1.append("</tr>");
                title1.append("</tr>");

                title2.append("<tr class=\"titleTr\">");
                html2.append("<tr class=\"conTr\">");
                for (int n = twelve; n < twentyFour; n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getOrderTotalAmount());
                    title2.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html2.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html2.append("</tr>");
                title2.append("</tr>");

                title3.append("<tr class=\"titleTr\">");
                html3.append("<tr class=\"conTr\">");
                for (int n = twentyFour; n < list.size(); n++) {
                    NumberFormat nf = NumberFormat.getInstance();
                    //nf.setGroupingUsed(false);//设为true则使用分组方式显示数据，即每三位数为一个分组，分组间以英文半角逗号分隔。
                    String amount = nf.format(list.get(n).getOrderTotalAmount());
                    title3.append("<td width='100px' class=\"titleTd\">" + list.get(n).getProvince() + "</td>");
                    html3.append("<td id=\"salesAmount\" width='100px' class=\"conTd\">" + amount + "</td>");
                }
                html3.append("</tr>");
                title3.append("</tr>");
            }
        }
        html1 = title1.append(html1);
        html2 = title2.append(html2);
        html3 = title3.append(html3);
        StringBuilder html = new StringBuilder("");

        html = title.append(html1.toString() + html2.toString() + html3.toString());
        html.append("</table>");
        html.append("</div>");
        String result = "";
        result = html.toString();
        return result;
    }

    /**
     * @param order HuangLJ
     *              插入更新订单头和行
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public SaleOrder upsertHeadAndLine(SaleOrder order) throws Exception {
        SaleOrder ord = new SaleOrder();
        try {


            Double rebatePercent = 0.0;
            Long acctId = order.getAcctId();
            Account account = new Account();
            account.setId(acctId);
            account = accountService.queryById(account);
            if (account == null) {
                throw new ServiceException("ORDER-037",acctId.toString());
            }
            if (account.getOrgId() == null) {
                throw new ServiceException("ORDER-038",acctId.toString());
            }
            if (order.getRebatePercent() == null) {
                rebatePercent = account.getRebatePercent();
                if (rebatePercent == null) {
                    rebatePercent = 0.0;
                }
                order.setRebatePercent(rebatePercent);
            }

            //获取订单上的价格表信息
            //如果不存在价格表，则获取客户对应的价格表放入订单上
            //如果存在，则基于当前价格表设置行上面的销售价上面
            Long priceListId = order.getPriceListId();
            if (priceListId == null) {
                //如果当前价格表为空，则设置其价格表
                setOrderPriceList(order);
            }

            //设置订单大类
            preOrderKind(order);

            //设置安全性属性
            CoreUser user = UserUtil.getUser();
            if (user == null) {
                throw new ServiceException("PUBLIC-027");
            }
            if (user.getPostnId() == null) {
                throw new ServiceException("ORDER-039");
            }
            if (user.getOrgId() == null) {
                throw new ServiceException("ORDER-040");
            }
            Long id = order.getId();
            String newStr = "NEW";
            if ((id == null) || newStr.equals(order.getRow_status())) {
                //如果订单Id为空或者状态为新建，则新建订单。否则更新
                if (id == null) {
                    id = keyGenerateService.keyGenerate();
                    order.setId(id);
                }

                //设置订单价格信息
                order = setSaleOrderPrice(order);

                String ordNo = order.getOrderNo();
                if (StringUtils.isNull(ordNo)) {
                    //生成订单编号
                    order.setOrderNo(generateCodeSingleton.getOrderCodeStr());
                }

                String orgTypeLovType = order.getOrderTypeLovType();
                if (StringUtils.isNull(orgTypeLovType)) {
                    order.setOrderTypeLovType("SalesOrder");
                }

                //设置安全性信息
                order.setCreatedBy(user.getId());
                order.setPostnId(user.getPostnId());
                Long orgId = order.getOrgId();
                if (orgId == null) {
                    order.setOrgId(user.getOrgId());
                }
                //绑定下单客户的主要职位id  ，原因(用于统计销售人员的下单情况)
                order.setSalePostnId(account.getPostnId());
                //插入头
                this.insert(order);

                //插入行
                List<SaleOrderItem> ordList = order.getSaleOrderItemList();
                for (SaleOrderItem item : ordList) {
                    if (item.getId() != null) {
                        throw new ServiceException("ORDER-041");
                    }
                    item.setCreatedBy(user.getId());
                    item.setPostnId(user.getPostnId());
                    item.setOrgId(user.getOrgId());
                    item.setLastUpdatedBy(user.getId());

                    item.setHeadId(id);
                    saleOrderItemService.insert(item);
                }
            } else {
                //设置订单价格信息
                order = setSaleOrderPrice(order);
                //更新
                order.setLastUpdatedBy(user.getId());
                order.setOrgId(user.getOrgId());
                this.update(order);
                //查询出当前系统中的订单行
                List<SaleOrderItem> saleOrderItemListOld = saleOrderItemService.querylistByOrderId(id);
                //当前传入的订单行
                List<SaleOrderItem> saleOrderItemList = order.getSaleOrderItemList();
                //比较，把没有的删掉。把新增的加入

                for (SaleOrderItem saleOrderItemOld : saleOrderItemListOld) {
                    Long itemId = saleOrderItemOld.getId();
                    boolean existFlag = false;
                    for (SaleOrderItem saleOrderItemNew : saleOrderItemList) {
                        //把没有的删除掉
                        Long newItemId = saleOrderItemNew.getId();
                        if (newItemId != null && itemId.equals(newItemId)) {
                            existFlag = true;
                            break;
                        }
                    }
                    if (!existFlag) {
                        //把没有的删掉
                        saleOrderItemService.deleteById(saleOrderItemOld);
                    }
                }
                for (SaleOrderItem item : saleOrderItemList) {
                    item.setHeadId(id);
                    //设置订单价格信息
                    if (item.getId() == null) {
                        saleOrderItemService.insert(item);
                    } else {
                        saleOrderItemService.update(item);
                    }
                }
            }
            ord = this.queryOneById(id);
            List<SaleOrderItem> ordList = saleOrderItemService.querylistByOrderId(id);
            ord.setSaleOrderItemList(ordList);
            return ord;
        } catch (Exception e) {
            LCLogger.withException(e);
            throw e;
        }
    }

    private Long getCurrentUserPriceId() throws Exception {
        CoreUser user = UserUtil.getUser();
        Long acctId = user.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PUBLIC-026");
        }
        Account accountQuery = new Account();
        accountQuery.setId(acctId);
        Account account = accountService.queryById(accountQuery);
        //客户组织Id
        Long accountOrgId = account.getOrgId();
        if (accountOrgId == null) {
            throw new ServiceException("PUBLIC-004");
        }
        Orgnization orgnizationQuery = new Orgnization();
        orgnizationQuery.setId(accountOrgId);
        Orgnization orgnization = orgnizationService.queryById(orgnizationQuery);
        if (orgnization == null) {
            throw new ServiceException("PUBLIC-055");
        }
        Long newPriceListId = orgnization.getPriceListId();
        if (newPriceListId == null) {
            throw new ServiceException("ORDER-042");
        }
        return newPriceListId;
    }


    @Override
    public int selectCountByacctId(SaleOrder order) throws Exception {
        return saleOrderMapper.selectCountByacctId(order);
    }

    /**
     * @param order 订单对象
     * @return comments 校验订单产品是否符合规则
     * @auther HuangLJ
     */
    public void checkOrderProductAndPrice(SaleOrder order) throws Exception {
        StringBuilder errMsg = new StringBuilder("");
        Double orderAmount = 0d;
        Long priceListId = order.getPriceListId();
        List<SaleOrderItem> saleOrderItemList = order.getSaleOrderItemList();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                //如果是赠品，则略过
                continue;
            }
            Long prodId = saleOrderItem.getProdId();
            PriceListItem priceListItemQuery = new PriceListItem();
            priceListItemQuery.setProdId(prodId);
            priceListItemQuery.setHeadId(priceListId);
            List<PriceListItem> priceListItemList = priceListItemService.queryByProdId(priceListItemQuery);
            if (priceListItemList == null || priceListItemList.size() < 1) {
                errMsg.append("\r\n行产品【").append(saleOrderItem.getProdName()).append("】没有在价格表中找到！");
            } else {
                Double promotionPrice = priceListItemList.get(0).getPromoPrice();
                if (!Objects.equals(promotionPrice, saleOrderItem.getPromotionPrice())) {
                    errMsg.append("\r\n行产品【").append(saleOrderItem.getProdName()).append("】校验价格报错！");
                } else {
                    orderAmount += promotionPrice;
                }
            }
        }
        if (!Objects.equals(orderAmount, order.getOrderAmount())) {
            errMsg.append("\r\n订单金额有误！");
        }
        if (!"".equals(errMsg.toString())) {
            throw new ServiceException(errMsg.toString());
        }
    }

    /**
     * @param saleOrder 订单对象
     * @return 返回值SaleOrder
     * HuangLJ
     * 基于价格表设置订单以及订单行价格
     */
    private SaleOrder setSaleOrderPrice(SaleOrder saleOrder) throws Exception {
        Long priceListId = saleOrder.getPriceListId();

        if (priceListId == null) {
            throw new ServiceException("ORDER-043");
        }
        //订单头上面的订单金额
        Double orderAmount = 0d;
        Double orderTotalAmount = 0d;
        for (int i = 0; saleOrder.getSaleOrderItemList() != null && i < saleOrder.getSaleOrderItemList().size(); ++i) {
            Double qty = saleOrder.getSaleOrderItemList().get(i).getQty();
            if (qty == null || qty < 1) {
                throw new ServiceException("ORDER-044");
            }
            String itemType = saleOrder.getSaleOrderItemList().get(i).getItemType();
            if ("Gift Item".equals(itemType)) {
                continue; //如果是赠品，则略过
            }
            SaleOrderItem saleOrderItem = saleOrder.getSaleOrderItemList().get(i);
            Long prodId = saleOrderItem.getProdId();
            if (prodId == null) {
                throw new ServiceException("ORDER-022");
            }
            PriceListItem priceListItemQuery = new PriceListItem();
            priceListItemQuery.setProdId(prodId);
            priceListItemQuery.setHeadId(priceListId);
            //查询指定id的产品
            List<PriceListItem> priceListItemList = priceListItemService.queryByProdId(priceListItemQuery);
            if (priceListItemList != null && priceListItemList.size() > 0) {
                PriceListItem priceListItem = priceListItemList.get(0);

                Double promotionPrice = priceListItem.getPromoPrice();

                if (promotionPrice == null) {
                    throw new ServiceException("ORDER-045",priceListItem.getProdId().toString());
                }
                Double netPrice = saleOrder.getSaleOrderItemList().get(i).getPolicyPrice();
                Double manualPrice = saleOrder.getSaleOrderItemList().get(i).getManualPrice();
                if (manualPrice != null && manualPrice > 0) {
                    netPrice = manualPrice;
                }
                if (promotionPrice == 0) {
                    promotionPrice = 0.0;
                }
                Double basePrice = priceListItem.getPrice();
                saleOrder.getSaleOrderItemList().get(i).setPromotionPrice(promotionPrice);
                saleOrder.getSaleOrderItemList().get(i).setBasePrice(basePrice);
                if (netPrice != null && netPrice > 0) {
                    saleOrder.getSaleOrderItemList().get(i).setNetPrice(netPrice);
                    saleOrder.getSaleOrderItemList().get(i).setAmount(qty * netPrice);
                    orderTotalAmount = orderTotalAmount + (netPrice * qty);
                } else {
                    saleOrder.getSaleOrderItemList().get(i).setNetPrice(promotionPrice);
                    saleOrder.getSaleOrderItemList().get(i).setAmount(qty * promotionPrice);
                    orderTotalAmount = orderTotalAmount + (promotionPrice * qty);
                }
                orderAmount = orderAmount + (promotionPrice * qty);
            } else {
                throw new ServiceException("ORDER-046",saleOrder.getSaleOrderItemList().get(i).getProdName());
            }
        }

        //整单折扣
        Double orderDiscount = saleOrder.getOrderDiscount();
        if (orderDiscount != null && orderDiscount > 0) {
            orderTotalAmount = orderTotalAmount - orderDiscount;
        }
        //运费
        Double freight = saleOrder.getFreight();
        if (freight != null) {
            orderTotalAmount = orderTotalAmount + freight;
        }
        saleOrder.setOrderAmount(orderAmount);
        saleOrder.setOrderTotalAmount(orderTotalAmount);
        setAccountPay(saleOrder);
        return saleOrder;
    }

    /**
     * @param saleOrder 订单对象
     *                  HuangLJ
     *                  校验客户的可售权限
     */
    @Override
    public String checkCanSale(SaleOrder saleOrder) throws Exception {
        //存放错误信息
        StringBuilder errMsg = new StringBuilder("");
        Long acctId = saleOrder.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PUBLIC-026");
        }
        //       String salesPartyName = saleOrder.getSalesPartyName();
//      Account accountQuery = new Account();
//      accountQuery.setId(salesPartyId);
//      Account account = accountService.queryById(accountQuery);
        SaleCategory saleCategoryQuery = new SaleCategory();
        saleCategoryQuery.setAccntId(acctId);
        saleCategoryQuery.setTotalFlag(true);
        saleCategoryQuery.setPageFlag(false);
        //获取对应的客户可售品类
        List<SaleCategory> saleCategoryList = saleCategoryService.queryByAccntId(saleCategoryQuery);

        //比较客户可售品类和订单的产品是否符合
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            //依次比较
            //产品名称
            String productName = saleOrderItem.getProdName();

            //产品品牌 一二三级
            String prodBrand = saleOrderItem.getProdBrand();
            String prodSecBrand = saleOrderItem.getProdSecBrand();
            String prodThirdBrand = saleOrderItem.getProdThirdBrand();

            //产品系列 一二三级
            String prodMatSeries = saleOrderItem.getProdMatSeries();
            String prodSecMatSeries = saleOrderItem.getProdSecSeries();
            String prodThirdMatSeries = saleOrderItem.getProdThirdSeries();

            //产品Id
            Long prodId = saleOrderItem.getProdId();
            if (prodId == null) {
                throw new ServiceException("ORDER-022");
            }

            //单品可售标识
            boolean canSaleProductFlag = false;
            //品牌可售标识
            boolean canSaleBrandFlag = false;
            //系列可售标识
            boolean canSaleSeriesFlag = false;
            for (SaleCategory SaleCategory : saleCategoryList) {
                String saleCateType = SaleCategory.getSaleCateType();
                if ("Product".equals(saleCateType)) {
                    //如果是单品，则 比较产品Id
                    if (prodId.equals(SaleCategory.getProductId())) {
                        canSaleProductFlag = true;
                        break;
                    }
                } else if ("ProductSeries".equals(saleCateType)) {
                    //如果是产品系列 则比较值列表
                    String saleCateName = SaleCategory.getSaleCateName();
                    if (saleCateName.equals(prodMatSeries) || saleCateName.equals(prodSecMatSeries) || saleCateName.equals(prodThirdMatSeries)) {
                        canSaleSeriesFlag = true;
                        break;
                    }
                } else if ("ProductBrand".equals(saleCateType)) {
                    //产品品牌
                    String saleCateName = SaleCategory.getSaleCateName();
                    if (saleCateName.equals(prodBrand) || saleCateName.equals(prodSecBrand) || saleCateName.equals(prodThirdBrand)) {
                        canSaleBrandFlag = true;
                        break;
                    }
                }
            }
            if (!canSaleProductFlag && !canSaleBrandFlag && !canSaleSeriesFlag) {
                errMsg.append("\n\r产品【").append(productName).append("】不属于客户【").append(acctId).append("】的可售产品!");
            }
        }
        if (errMsg.length() > 0) {
            return errMsg.toString();
        } else {
            return "";
        }
    }

    /**
     * @param saleOrder 订单对象
     *                  HuangLJ
     *                  校验客户的资金账户
     */
    @Override
    public String checkDealerAccount(SaleOrder saleOrder) throws Exception {
        //应付金额
        Double orderTotalAmount = saleOrder.getOrderTotalAmount();
        //返利百分比
        Double rebatePercent = saleOrder.getRebatePercent();

        if (orderTotalAmount == null || rebatePercent == null) {
            throw new ServiceException("ORDER-047");
        }

        //获取客户当前可用金额
        DealerAccount dealerAccountQuery = new DealerAccount();
        dealerAccountQuery.setAccntId(saleOrder.getAcctId());
        List<DealerAccount> dealerAccountList = dealerAccountService.queryByAccountId(dealerAccountQuery);

        //分别获取返利账户和现金账户
        // 返利账户
        Double amountRebate = 0d;
        //现金账户
        Double amount = 0d;
        //现金账户可用余额
        Double availableBalance = 0d;
        // 返利账户可用余额
        Double availableBalanceRebate = 0d;
        //表示查询除了多条返利账户
        boolean muitRetFlag = false;
        //表示查询出了多条现金账户
        boolean muitCashFlag = false;
        for (DealerAccount dealerAccount : dealerAccountList) {
            String accountType = dealerAccount.getType();
            if ("Return Account".equals(accountType)) {
                if (muitRetFlag) {
                    String accType = LovUtil.getLovName("DEALER_ACCOUNT_TYPE", "Return Account");
                    throw new ServiceException("ORDER-048",saleOrder.getAcctId().toString(),accType);
                }
                muitRetFlag = true;
                //返利账户，设置返利账户金额
                amountRebate = dealerAccount.getAmount();
                //返利账户可用余额
                availableBalanceRebate = dealerAccount.getAvailableBalance();
            } else if ("Cash Account".equals(accountType)) {
                if (muitCashFlag) {
                    String accType = LovUtil.getLovName("DEALER_ACCOUNT_TYPE", "Cash Account");
                    throw new ServiceException("ORDER-048",saleOrder.getAcctId().toString(),accType);
                }
                muitCashFlag = true;
                //现金账户，设置现金账户金额
                amount = dealerAccount.getAmount();
                //可用余额
                availableBalance = dealerAccount.getAvailableBalance();
            }
        }

        //校验金额是否满足条件
        //计算返利应付
        Double rebatePayable = orderTotalAmount * (rebatePercent / 100);
        // 当前返利账户余额小于此订单返利金额，设置返利金额等于当前返利账户余额
        if (rebatePayable > availableBalanceRebate) {
            rebatePayable = availableBalanceRebate;
        }
        if (rebatePayable < 0.0) {
            rebatePayable = 0.0;
        }
        //计算现金应付
        Double payableAmount = orderTotalAmount - rebatePayable;

        //存放错误信息
        StringBuilder errMsg = new StringBuilder();
        //比较，如果任一账户达不到要求，则报错。
        String flag = "Y";
        if (payableAmount > availableBalance && flag.equals(saleOrder.getAttr1())) {
            errMsg.append("\r\n").append(LovUtil.getLovName("DEALER_ACCOUNT_TYPE", "Cash Account")).append("不足。");
        }
        //设置余额应付
        saleOrder.setMoneyWithdrawing(payableAmount);
        //设置返利应付
        saleOrder.setRebateMoney(rebatePayable);
        //设置现金支付为0
        saleOrder.setCash(0.0);
        if (errMsg.length() > 0) {
            return errMsg.toString();
        } else {
            return "";
        }
    }


    /**
     * HuanglJ 设置当前订单对应的返利，以及账户应付金额
     *
     * @param saleOrder 订单对象
     * @throws Exception 常规
     */
    private void setAccountPay(SaleOrder saleOrder) throws Exception {
        //应付金额
        Double orderTotalAmount = saleOrder.getOrderTotalAmount();
        //返利百分比
        Double rebatePercent = saleOrder.getRebatePercent();
        String payType = saleOrder.getPayType();

        String cashPayment = "CashPayment";
        if (cashPayment.equals(payType)) {
            //账户支付
            //设置订单应付金额
            saleOrder.setCash(orderTotalAmount);
            //设置返利应付为0
            saleOrder.setRebateMoney(0.0);

            //设置余额应付为0
            saleOrder.setMoneyWithdrawing(0.0);

        }
        String accountBalancePayment = "AccountBalancePayment";
        if (accountBalancePayment.equals(payType)) {
            if (orderTotalAmount == null || rebatePercent == null) {
                throw new ServiceException("ORDER-047");
            }
            //计算返利应付
            Double rebatePayable = saleOrder.getRebateMoney();
            if (null == rebatePayable) {
                rebatePayable = orderTotalAmount * (rebatePercent / 100);
                saleOrder.setRebateMoney(rebatePayable);
            }
            //计算现金应付
            Double payableAmount = orderTotalAmount - rebatePayable;
            saleOrder.setMoneyWithdrawing(payableAmount);

        }
    }

    /**
     * HuangLJ
     * 审核订单
     * 当前端点击审核订单的时候，校验订单的可售权限，生成政策信息，校验库存，校验金额
     * 如果校验通过，则生成资金占用记录。修改付款状态为已付款，设置订单状态为已审核
     *
     * @param saleOrderAtr 订单对象
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void orderVerify(SaleOrder saleOrderAtr) throws Exception {

        //通过传入的ID查询
        SaleOrder saleOrder = this.queryById(saleOrderAtr);
        List<SaleOrderItem> saleOrderItemList = saleOrderItemService.querylistByOrderId(saleOrder.getId());
        saleOrder.setSaleOrderItemList(saleOrderItemList);
        String status = saleOrder.getStatus();
        String submitted = "Submitted";
        if (!submitted.equals(status)) {
            throw new ServiceException("ORDER-032");
        }
        //先查询出对应的客户和类型的资金账户的Id
        // 先调用订单确认方法。获取相关信息
        String errMsg = this.confirm(saleOrder);
        if (!StringUtils.isNull(errMsg)) {
            throw new ServiceException(errMsg);
        }
        Long accountId = saleOrder.getAcctId();
        //余额应付
        Double moneyWithdrawing = saleOrder.getMoneyWithdrawing();
        //返利应付
        Double rebateMoney = saleOrder.getRebateMoney();

        //校验通过之后，创建相关的账户占用记录
        if (moneyWithdrawing != null && moneyWithdrawing > 0) {
            //生成余额账户交易记录
            generateAccount(accountId, "Cash Account", "OrderPaymentOccupy", moneyWithdrawing, saleOrder, true);
        }

        if (rebateMoney != null && rebateMoney > 0) {
            //生成返利账户交易记录
            generateAccount(accountId, "Return Account", "OrderPaymentOccupy", rebateMoney, saleOrder, true);
        }
        //更新付款状态状态
        SaleOrder saleOrderUpd = new SaleOrder();
        //已批准，更新订单状态
        saleOrderUpd.setStatus("Approved");
        //支付状态为已支付
        saleOrderUpd.setPayStatus("AlreadyPaid");
        saleOrderUpd.setId(saleOrderAtr.getId());
        //更新付款状态
        this.orderStatusUpdate(saleOrderUpd);

        pushService.sampleMessageOnlyUser("订单【" + saleOrder.getOrderNo() + "】已经审核！", saleOrder.getCreatedBy());
    }

    /**
     * HuangLJ
     * 审核提交
     * 当前端点击审核订单的时候，校验订单的可售权限，生成政策信息，校验库存，校验金额
     * 如果校验通过，则生成资金占用记录。修改付款状态为已付款，设置订单状态为已审核
     *
     * @param saleOrder 订单对象
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void orderCommit(SaleOrder saleOrder) throws Exception {
        //更新新状态
        SaleOrder validateObj = queryById(saleOrder);
        if (validateObj != null) {
            boolean flagTwo = (!StringUtils.equals(validateObj.getStatus(), "New") && !StringUtils.equals(validateObj.getStatus(), "Rejected"));
            if (flagTwo) {
                throw new ServiceException("ORDER-029");
            }
        }
        //先查询出对应的客户和类型的资金账户的Id
        // 先调用订单确认方法。获取相关信息
        String errMsg = this.confirm(saleOrder);
        if (!StringUtils.isNull(errMsg)) {
            throw new ServiceException(errMsg);
        }
        saleOrder.setStatus("Submitted");
        saleOrderMapper.orderCommitUpdate(saleOrder);
    }


    /**
     * HuangLJ 订单确认 订单确认会对订单做一系列的校验，包括可售权限，政策，库存以及资金
     * 返回的字符串如果不为空，则表示有报错。否则，正常
     *
     * @param saleOrder 订单对象
     * @throws Exception 报错
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public String confirm(SaleOrder saleOrder) throws Exception {
        preOrderKind(saleOrder);
        String errMsg = "";
        String orderFirstType = saleOrder.getOrderType();
        String orderChildType = saleOrder.getOrderChildType();
        String orderKind = saleOrder.getOrderKind();
        if (StringUtils.isNull(orderFirstType) || StringUtils.isNull(orderChildType) || StringUtils.isNull(orderKind)) {
            throw new ServiceException("ORDER-049");
        }

        //获取价格表信息
        //从销售订单中获取下单客户信息。把价格表挂上去
        Long acctId = saleOrder.getAcctId();
        Account account = new Account();
        account.setId(acctId);
        account = accountService.queryById(account);
        if (account == null) {
            throw new ServiceException("ORDER-050",acctId.toString());
        }
        //如果返利百分比为空，则设置
        Double rebatePercent = saleOrder.getRebatePercent();
        if (rebatePercent == null) {
            rebatePercent = account.getRebatePercent();
        }
        if (rebatePercent == null) {
            rebatePercent = 0.0;
        }
        saleOrder.setRebatePercent(rebatePercent);
        Long priceListId = saleOrder.getPriceListId();
        if (priceListId == null) {
            //如果当前价格表为空，则设置其价格表
            setOrderPriceList(saleOrder);
        }
        setSaleOrderPrice(saleOrder);
        //获取订单参数
        OrderPaySet orderPaySetQuery = new OrderPaySet();
        orderPaySetQuery.setOrderFirstType(orderFirstType);
        orderPaySetQuery.setOrderSecondType(orderChildType);
        orderPaySetQuery.setOrderKind(orderKind);
        OrderPaySet orderPaySet = orderPaySetService.getByOrderType(orderPaySetQuery);

        String flag = "Y";
        //校验可售权限，如果存在不可售产品，则报错！否则，则继续往下走
        if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckSaleFlag()) && flag.equals(orderPaySet.getCheckSaleFlag())) {
            errMsg = this.checkCanSale(saleOrder);
        }

        //获取政策
        if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckPolicyFlag()) && flag.equals(orderPaySet.getCheckPolicyFlag())) {
            //校验政策
            policyService.getPolicy(saleOrder);
        }

        //校验库存
        if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckStoredFlag()) && flag.equals(orderPaySet.getCheckStoredFlag())) {
            //校验库存
            LCLogger.info().withMessageKey("confirm")
                    .withMessage("校验库存！（无实际逻辑！）").flush();
        }

        setSaleOrderPrice(saleOrder);
        //支付类型
        String payType = saleOrder.getPayType();
        String cashPayment = "CashPayment";
        String accountBalancePayment = "AccountBalancePayment";
        //如果当前支付类型为现金支付，则走现金支付的逻辑，否则，走账户支付的逻辑
        if (cashPayment.equals(payType)) {
            //现金支付
            //设置订单应付金额
            saleOrder.setCash(saleOrder.getOrderTotalAmount());

            //设置返利应付为0
            saleOrder.setRebateMoney(0.0);

            //设置余额应付为0
            saleOrder.setMoneyWithdrawing(0.0);
        } else if (accountBalancePayment.equals(payType)) {
            if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckBalancedFlag())) {
                //账户支付
                //校验账户是否够用，不够，则报错。
                saleOrder.setAttr1(orderPaySet.getCheckBalancedFlag());
                errMsg = errMsg + this.checkDealerAccount(saleOrder);

            }
            //直接设置现相关的价钱
            //计算返利应付
            // 应付金额
            Double orderTotalAmount = saleOrder.getOrderTotalAmount();
            if (orderTotalAmount == null) {
                throw new ServiceException("ORDER-047");
            }
            //设置现金支付为0
            saleOrder.setCash(0.0);
        }
        saleOrder = this.upsertHeadAndLine(saleOrder);
        return errMsg;
    }

    /**
     * HuangLJ 订单确认 订单确认会对订单做一系列的校验，包括可售权限，政策，库存以及资金
     * 返回的字符串如果不为空，则表示有报错。否则，正常
     *
     * @param saleOrder 订单对象
     * @throws Exception 报错
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public String dmsConfirm(SaleOrder saleOrder) throws Exception {
        preOrderKind(saleOrder);
        String errMsg = "";
        String orderFirstType = saleOrder.getOrderType();
        String orderChildType = saleOrder.getOrderChildType();
        String orderKind = saleOrder.getOrderKind();
        if (StringUtils.isNull(orderFirstType) || StringUtils.isNull(orderChildType) || StringUtils.isNull(orderKind)) {
            throw new ServiceException("ORDER-049");
        }
        //获取价格表信息
        //从销售订单中获取下单客户信息。把价格表挂上去
        Long acctId = saleOrder.getAcctId();
        Account account = new Account();
        account.setId(acctId);
        account = accountService.queryById(account);
        if (account == null) {
            throw new ServiceException("ORDER-050",acctId.toString());
        }
        //如果返利百分比为空，则设置
        Double rebatePercent = saleOrder.getRebatePercent();
        if (rebatePercent == null) {
            rebatePercent = account.getRebatePercent();
        }
        if (rebatePercent == null) {
            rebatePercent = 0.0;
        }
        saleOrder.setRebatePercent(rebatePercent);
        Long priceListId = saleOrder.getPriceListId();
        if (priceListId == null) {
            //如果当前价格表为空，则设置其价格表
            setOrderPriceList(saleOrder);
        }

        setSaleOrderPrice(saleOrder);
        //获取订单参数
        OrderPaySet orderPaySetQuery = new OrderPaySet();
        orderPaySetQuery.setOrderFirstType(orderFirstType);
        orderPaySetQuery.setOrderSecondType(orderChildType);
        orderPaySetQuery.setOrderKind(orderKind);
        OrderPaySet orderPaySet = orderPaySetService.getByOrderType(orderPaySetQuery);

        String flag = "Y";
        //获取政策
        if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckPolicyFlag()) && flag.equals(orderPaySet.getCheckPolicyFlag())) {
            //校验政策
            policyService.getPolicy(saleOrder);
        }

        setSaleOrderPrice(saleOrder);
        //支付类型
        String payType = saleOrder.getPayType();
        String cashPayment = "CashPayment";
        String accountBalancePayment = "AccountBalancePayment";
        //如果当前支付类型为现金支付，则走现金支付的逻辑，否则，走账户支付的逻辑
        if (cashPayment.equals(payType)) {
            //现金支付
            //设置订单应付金额
            saleOrder.setCash(saleOrder.getOrderTotalAmount());

            //设置返利应付为0
            saleOrder.setRebateMoney(0.0);

            //设置余额应付为0
            saleOrder.setMoneyWithdrawing(0.0);
        } else if (accountBalancePayment.equals(payType)) {
            if (orderPaySet != null && !StringUtils.isNull(orderPaySet.getCheckBalancedFlag())) {
                //账户支付
                //校验账户是否够用，不够，则报错。
                saleOrder.setAttr1(orderPaySet.getCheckBalancedFlag());
                errMsg = errMsg + this.checkDealerAccount(saleOrder);

            }
            //直接设置现相关的价钱
            //计算返利应付
            // 应付金额
            Double orderTotalAmount = saleOrder.getOrderTotalAmount();
            if (orderTotalAmount == null) {
                throw new ServiceException("ORDER-047");
            }
            Double rebatePayable = orderTotalAmount * (rebatePercent / 100);

            //计算现金应付
            Double payableAmount = orderTotalAmount - rebatePayable;
        }
        return errMsg;
    }

    /**
     * HuangLJ 生成资金账户交易记录
     *
     * @param accountId        客户Id
     * @param accountType      账户类型
     * @param transactionType  交易类型
     * @param transactionPrice 交易金额 都给正数，
     * @param saleOrder        订单
     * @param pm               交易金额是否给正负值，默认 true 负
     * @throws Exception 报错
     */
    private void generateAccount(Long accountId, String accountType, String transactionType,
                                 Double transactionPrice, SaleOrder saleOrder, boolean pm) throws Exception {

        if (transactionPrice < 0) {
            throw new ServiceException("ORDER-051");
        }
        Double transactionPriceNew = transactionPrice;
        String orderPaymentOccupy = "OrderPaymentOccupy";
        String orderPayment = "OrderPayment";
        if (orderPaymentOccupy.equals(transactionType) || orderPayment.equals(transactionType)) {
            //根据交易类型，设置当前金额的符号。
            //如果是 订单扣款-释放 ，则给正值
            //如果是 订单扣款-花费 订单扣款-占用 ，则给负值
            if (pm) {
                transactionPriceNew = 0 - transactionPriceNew;
            }
        }

        DealerAccount dealerAccountQuery = new DealerAccount();
        dealerAccountQuery.setAccntId(accountId);
        dealerAccountQuery.setType(accountType);
        dealerAccountQuery.setPageFlag(false);
        dealerAccountQuery.setTotalFlag(true);
        List<DealerAccount> dealerAccountList = dealerAccountService.queryByExamplePage(dealerAccountQuery);
        if (dealerAccountList == null || dealerAccountList.size() == 0) {
            throw new ServiceException("ORDER-052",accountId.toString(),LovUtil.getLovName("DEALER_ACCOUNT_TYPE", accountType));
        }
        if (dealerAccountList.size() > 1) {
            throw new ServiceException("ORDER-053",accountId.toString(),LovUtil.getLovName("DEALER_ACCOUNT_TYPE", accountType));
        }


        //注意，这个地方是账户id，而不是客户id
        Long acctId = dealerAccountList.get(0).getId();

        DealerTransactionDetail dealerTransactionDetail = new DealerTransactionDetail();
        dealerTransactionDetail.setHeadId(acctId);
        dealerTransactionDetail.setAmount(transactionPriceNew);
        dealerTransactionDetail.setSourceType(transactionType);
        dealerTransactionDetail.setSourceId(saleOrder.getId());
        dealerTransactionDetail.setSourceNum(saleOrder.getOrderNo());
        dealerTransactionDetailService.insert(dealerTransactionDetail);
    }

    /**
     * HuangLJ
     * 订单完成
     *
     * @param saleOrder 订单对象
     */
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public void complete(SaleOrder saleOrder) throws Exception {
        SaleOrder saleOrderOld = this.queryById(saleOrder.getId());
        if (saleOrderOld == null) {
            throw new ServiceException("ORDER-054",saleOrder.getId().toString());
        }
        String shipped = "Shipped";
        if (!shipped.equals(saleOrderOld.getStatus())) {
            throw new ServiceException("ORDER-055");
        }
        Long accountId = saleOrderOld.getAcctId();
        //创建对应的资金占用记录
        // 余额应付
        Double moneyWithdrawing = saleOrderOld.getMoneyWithdrawing();
        //返利应付
        Double rebateMoney = saleOrderOld.getRebateMoney();
        //校验通过之后，创建相关的账户占用记录
        if (moneyWithdrawing != null && moneyWithdrawing > 0) {
            //生成余额账户资金释放记录
            generateAccount(accountId, "Cash Account", "OrderPaymentRelease", moneyWithdrawing, saleOrderOld, true);

            //生成余额账户资花费放记录
            generateAccount(accountId, "Cash Account", "OrderPayment", moneyWithdrawing, saleOrderOld, true);
        }

        if (rebateMoney != null && rebateMoney > 0) {
            //生成余额账户资金释放记录
            generateAccount(accountId, "Return Account", "OrderPaymentRelease", rebateMoney, saleOrderOld, true);

            //生成余额账户资花费放记录
            generateAccount(accountId, "Return Account", "OrderPayment", rebateMoney, saleOrderOld, true);
        }
        //更新付款状态状态
        SaleOrder saleOrderUpd = new SaleOrder();
        //已完成
        saleOrderUpd.setStatus("Closed");
        saleOrderUpd.setId(saleOrder.getId());
        //更新付款状态
        this.orderStatusUpdate(saleOrderUpd);
        pushService.sampleMessageOnlyUser("订单【" + saleOrderOld.getOrderNo() + "】已经完成！", saleOrderOld.getCreatedBy());
    }

    /**
     * Hlj 退货单更新状态 2018年06月04日
     *
     * @param saleOrderAtr 订单对象
     * @throws Exception 报错
     */
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public void returnOrdUpdateStatus(SaleOrder saleOrderAtr) throws Exception {
        Long id = saleOrderAtr.getId();
        //通过传入的ID查询
        SaleOrder saleOrder = this.queryById(saleOrderAtr);
        if (saleOrder == null) {
            throw new ServiceException("ORDER-054",id.toString());
        }
        //如果不是退货订单，则报错
        String orderType = saleOrder.getOrderType();
        String salesReturnOrder = "SalesReturnOrder";
        if (!salesReturnOrder.equals(orderType)) {
            throw new ServiceException("ORDER-056");
        }

        //判断状态是否合理
        String ordStatus = saleOrder.getStatus();
        String ordPayStatus = saleOrder.getPayStatus();
        String newOrdPayStatus = saleOrderAtr.getPayStatus();
        if (!StringUtils.isNull(newOrdPayStatus)) {
            throw new ServiceException("ORDER-057");
        }
        String newStatus = saleOrderAtr.getStatus();
        String submitted = "Submitted";
        String newStr = "New";
        String rejected = "Rejected";
        if (submitted.equals(newStatus)) {
            if (!newStr.equals(ordStatus) && !rejected.equals(ordStatus)) {
                throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
            }
        }
        String approved = "Approved";
        if (approved.equals(newStatus)) {
            if (!submitted.equals(ordStatus)) {
                throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
            }
        }
        String closed = "Closed";
        String refunded = "Refunded";
        if (closed.equals(newStatus)) {
            if (!approved.equals(ordStatus)) {
                throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
            }

            if (!refunded.equals(ordPayStatus)) {
                throw new ServiceException("ORDER-059");
            }
        }
        if (rejected.equals(newStatus)) {
            if (!submitted.equals(ordStatus)) {
                throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
            }
        }
        String cancelled = "Cancelled";
        if (cancelled.equals(newStatus)) {
            if (!newStr.equals(ordStatus) && !submitted.equals(ordStatus) && !rejected.equals(ordStatus)) {
                throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
            }
        }
        saleOrderMapper.orderStatusUpdate(saleOrderAtr);
        //增加消息生成逻辑
        pushService.sampleMessageOnlyUser("退货订单【" + saleOrder.getOrderNo() + "】已经"
                + LovUtil.getLovName("ORDER_STATUS", saleOrderAtr.getStatus()) + "！",
                saleOrder.getCreatedBy());
    }

    /**
     * Hlj 退货订单退款 2018年06月04日
     *
     * @param saleOrderAtr 订单对象
     * @throws Exception 报错
     */
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public void returnOrderRefund(SaleOrder saleOrderAtr) throws Exception {
        Long id = saleOrderAtr.getId();
        if (id == null) {
            throw new ServiceException("ORDER-18");
        }
        SaleOrder saleOrder = queryById(saleOrderAtr);
        if (saleOrder == null) {
            throw new ServiceException("ORDER-054",id.toString());
        }

        String ordStatus = saleOrder.getStatus();
        String payStatus = saleOrder.getPayStatus();
        String approved = "Approved";
        if (!approved.equals(ordStatus)) {
            throw new ServiceException("ORDER-058",LovUtil.getLovName("ORDER_STATUS", ordStatus));
        }
        String unrefunded = "Unrefunded";
        if (!unrefunded.equals(payStatus)) {
            throw new ServiceException("ORDER-060",LovUtil.getLovName("REFUND_TYPE", payStatus));
        }
        //应退金额
        Double ordTotalAmount = saleOrder.getOrderTotalAmount();
        //下单客户
        Long acctId = saleOrder.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PUBLIC-026");
        }
        if (ordTotalAmount == null) {
            throw new ServiceException("ORDER-061");
        }
        //退款方式
        String payType = saleOrder.getPayType();
        String accountBalanceRefund = "AccountBalanceRefund";
        String cashRefund = "CashRefund";
        if (accountBalanceRefund.equals(payType)) {
            //账户支付
            //生成账户明细 OrderPayment
            generateAccount(acctId, "Cash Account", "OrderPayment", ordTotalAmount, saleOrder, false);
        } else if (cashRefund.equals(payType)) {
            //现金支付
            //更新状态为已退款
        } else {
            throw new ServiceException("ORDER-062");
        }
        SaleOrder saleOrderUpd = new SaleOrder();
        saleOrderUpd.setId(id);
        saleOrderUpd.setPayStatus("Refunded");
        saleOrderMapper.payStatusUpdate(saleOrderUpd);
    }

    /**
     * @param saleOrder 订单对象
     * @throws Exception 报错
     */
    private void preOrderKind(SaleOrder saleOrder) throws Exception {
        Long salesPatyId = saleOrder.getSalesPartyId();
        if (salesPatyId == null) {
            throw new ServiceException("ORDER-063");
        }
        Account accountQuery = new Account();
        accountQuery.setId(salesPatyId);
        Account account = accountService.queryById(accountQuery);
        if (account == null) {
            throw new ServiceException("ORDER-064");
        }
        String type = account.getAcctType();
        String vendor = "Vendor";
        String dealer = "Dealer";
        String terminal = "Terminal";
        if (vendor.equals(type)) {
            saleOrder.setOrderKind("VendorOrder");
        } else if (dealer.equals(type)) {
            saleOrder.setOrderKind("DealerOrder");
        } else if (terminal.equals(type)) {
            saleOrder.setOrderKind("TerminalOrder");
        } else {
            throw new ServiceException("ORDER-065");
        }
    }

    /**
     * HuangLJ 2018年07月16日
     *
     * @param saleOrder 订单对象
     * @throws Exception 报错
     */
    private void setOrderPriceList(SaleOrder saleOrder) throws Exception {
        Long salesPatyId = saleOrder.getSalesPartyId();
        if (salesPatyId == null) {
            throw new ServiceException("ORDER-066");
        }
        Account accountQuery = new Account();
        accountQuery.setId(salesPatyId);
        Account account = accountService.queryById(accountQuery);
        if (account == null) {
            throw new ServiceException("ORDER-067");
        }
        String accntType = account.getAcctType();
        String vendor = "Vendor";
        if (vendor.equals(accntType)) {
            //品牌商，走自己的逻辑
            Long newPriceListId = account.getPriceListId();
            if (newPriceListId == null) {
                throw new ServiceException("ORDER-068");
            }
            saleOrder.setPriceListId(newPriceListId);
        } else {
            //客户组织Id
            Long accountOrgId = account.getOrgId();
            if (accountOrgId == null) {
                throw new ServiceException("ORDER-069");
            }
            Orgnization orgnizationQuery = new Orgnization();
            orgnizationQuery.setId(accountOrgId);
            Orgnization orgnization = orgnizationService.queryById(orgnizationQuery);
            if (orgnization == null) {
                throw new ServiceException("ORDER-070");
            }
            Long newPriceListId = orgnization.getPriceListId();
            if (newPriceListId == null) {
                throw new ServiceException("ORDER-071");
            }
            saleOrder.setPriceListId(newPriceListId);
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public SaleOrder outInInvtxn(SaleOrder saleOrder, List<SaleOrderItem> orderItemList, String invtxnType) throws Exception {
        if (saleOrder == null) {
            throw new ServiceException("ORDER-054","NULL");
        }
        if (orderItemList == null || orderItemList.isEmpty()) {
            throw new ServiceException("ORDER-072");
        }
        //销售订单号
        String orderNo = saleOrder.getOrderNo();
        //订单头的销售主体ID
        Long salesPartyId = saleOrder.getSalesPartyId();
        //订单头的收货客户ID
        Long shipAcctId = saleOrder.getShipAcctId();
        LCLogger.info().withMessageKey("outInInvtxn")
                .withMessage("订单头ID:" + saleOrder.getId()).flush();
        LCLogger.info().withMessageKey("outInInvtxn")
                .withMessage("订单头的销售主体ID:" + salesPartyId).flush();
        LCLogger.info().withMessageKey("outInInvtxn")
                .withMessage("订单头的收货客户ID:" + shipAcctId).flush();

        //销售主体（客户）的仓库
        Invloc salesPartyInvloc = null;
        //收货客户的仓库
        Invloc shipAcctInvloc = null;
        //虚拟仓库
        Invloc fictitiousInvloc = invlocService.getFictitiousInvloc();

        //来源仓库ID
        Long origInvlocId = null;
        //目的仓库ID
        Long desInvlocId = null;
        switch (invtxnType) {
            //采购入库
            case "purchasein":
                origInvlocId = fictitiousInvloc.getId();
                shipAcctInvloc = invlocService.getAccountInvloc(shipAcctId);
                desInvlocId = shipAcctInvloc.getId();
                break;
            //采购退货
            case "purchaseout":
                shipAcctInvloc = invlocService.getAccountInvloc(shipAcctId);
                origInvlocId = shipAcctInvloc.getId();
                desInvlocId = fictitiousInvloc.getId();
                //修改订单状态为"已发货"
//                saleOrder.setStatus("Shipped");
//                orderStatusUpdate(saleOrder);
                break;
            //销售出库
            case "salesout":
                salesPartyInvloc = invlocService.getAccountInvloc(salesPartyId);
                origInvlocId = salesPartyInvloc.getId();
                desInvlocId = fictitiousInvloc.getId();
                //修改订单状态为"已发货"
//                saleOrder.setStatus("Shipped");
//                orderStatusUpdate(saleOrder);
                break;
            //销售退货
            case "salesin":
                origInvlocId = fictitiousInvloc.getId();
                salesPartyInvloc = invlocService.getAccountInvloc(salesPartyId);
                desInvlocId = salesPartyInvloc.getId();
                //修改订单状态为"已完成"
//                saleOrder.setStatus("Closed");
//                orderStatusUpdate(saleOrder);
                break;
            default:
                throw new ServiceException("ORDER-073");
        }
        LCLogger.info().withMessageKey("outInInvtxn")
                .withMessage("来源仓库ID:" + origInvlocId).flush();
        LCLogger.info().withMessageKey("outInInvtxn")
                .withMessage("目的仓库ID:" + desInvlocId).flush();

        for (SaleOrderItem item : orderItemList) {
            //生成记录
            Invtxn invtxn = new Invtxn();
            Long prodId = item.getProdId();
            //添加交易记录:类型、来源仓库、目的仓库、来源客户、目的客户、源可用性、源状态、目的可用性、目的状态
            invtxn.setType(invtxnType);
            invtxn.setOrigInvlocId(origInvlocId);
            invtxn.setDesInvlocId(desInvlocId);
            invtxn.setProdId(prodId);

            //设置库存数量，库存数量 = 订单行的产品数量 * 产品的换算系数
            Product prod = productService.queryById(prodId);
            if (prod == null) {
                throw new ServiceException("ORDER-074", prodId.toString());
            }
            double amount = 0d;
            if (item.getProdUnit() == null) {
                throw new ServiceException("ORDER-075",item.getId().toString());
            }
            if (!item.getProdUnit().equals(prod.getStockUnit())) {
                amount = invtxnAmount(item.getThisQty(), prod.getConverConff());
            } else {
                amount = invtxnAmount(item.getThisQty(), "1");
            }
            invtxn.setAmount(amount);

            invtxn.setOrderId(item.getHeadId());
            invtxn.setTradeDate(DateUtil.dateToStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
            invtxn.setSourceId(item.getId());
            //huanglj 2018年07月23日 设置来源编号
            invtxn.setSourceNum(orderNo);
            invtxn.setOrigAvailability("in_hand");
            invtxn.setOrigStatus("good");
            invtxn.setDesAvailability("in_hand");
            invtxn.setDesStatus("good");
            CoreUser user = UserUtil.getUser();
            if (invtxn.getOrgId() == null) {
                invtxn.setOrgId(user.getOrgId());
            }
            invtxnService.insert(invtxn);
            invtxnService.goodConfirm(invtxn.getId());
        }
        return saleOrder;
    }

    /**
     * 生成库存交易数据时，计算一个订单行里的产品的库存数量，库存数量 = 订单行的产品数量 * 产品的换算系数
     * @author 何启谦
     * @param qty             产品数量
     * @param prodConverConff 产品的换算系数
     * @return 计算结果
     */
    private double invtxnAmount(double qty, String prodConverConff) {
        if (qty <= 0) {
            throw new ServiceException("ORDER-076",String.valueOf(qty));
        }
        double amount = 0d;
        if (StringUtils.isBlank(prodConverConff)) {
            prodConverConff = "1";
        }
        try {
            amount = qty * Double.parseDouble(prodConverConff);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("ORDER-077",prodConverConff);
        }
        //保留两位有效小数
        int decimalPlace = 2;
        amount = BigDecimal.valueOf(amount).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).doubleValue();
        return amount;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public SaleOrder arrivedOrderItem(List<SaleOrderItem> paramOrderItemList, String invtxnType) throws Exception {
        List<SaleOrderItem> orderItemList = checkArrivedOrderItem(paramOrderItemList);
        //获取实时的订单头对象
        SaleOrder saleOrder = queryById(orderItemList.get(0).getHeadId());

        //如果所有产品都到货完毕，则修改订单状态
        for (SaleOrderItem item : orderItemList) {
            //判断订单行到货数量是否和理:本次到货数量和已到货数量不能大于订单数量
            if (item.getArrivedQty() == null) {
                item.setArrivedQty(0d);
            }
            if (item.getThisQty() < 0 || item.getThisQty() == null) {
                throw new ServiceException("ORDER-078");
            }
            Double sum = Double.sum(item.getArrivedQty(), item.getThisQty());
            int compareResult = Double.compare(item.getQty(), sum);
            if (compareResult < 0) {
                throw new ServiceException("ORDER-078");
            }
            item.setArrivedQty(sum);
            saleOrderItemService.update(item);
        }

        //标记是否全部到货
        boolean allItemArrivedFlag = true;
        List<SaleOrderItem> allItemList = saleOrderItemService.querylistByOrderId(saleOrder.getId());
        for (SaleOrderItem item : allItemList) {
            if (item.getArrivedQty() == null) {
                item.setArrivedQty(0d);
            }
            if (item.getQty() == null) {
                item.setQty(0d);
            }
            if (Double.compare(item.getArrivedQty(), item.getQty()) != 0) {
                allItemArrivedFlag = false;
                break;
            }
        }

        //如果所有产品都到货完毕，则修改订单状态
        if (allItemArrivedFlag) {
            saleOrder.setStatus("Closed");
            orderStatusUpdate(saleOrder);
        }
        //创建库存交易
        outInInvtxn(saleOrder, orderItemList, invtxnType);
        return saleOrder;
    }

    /**
     * 到货确认：检查和填充订单行字段
     * @author 何启谦
     * @param paramOrderItemList 前端传过来的订单行
     * @return 处理完成后端订单行
     */
    private List<SaleOrderItem> checkArrivedOrderItem(List<SaleOrderItem> paramOrderItemList) throws Exception {
        if (paramOrderItemList == null || paramOrderItemList.size() == 0) {
            throw new ServiceException("ORDER-072");
        }
        //如果所有产品都到货完毕，则修改订单状态
        SaleOrderItem orderItem = saleOrderItemService.queryById(paramOrderItemList.get(0).getId());
        //获取订单头ID
        Long orderId = orderItem.getHeadId();
        //实时查询该订单头下的所有订单行
        List<SaleOrderItem> orderItemList = saleOrderItemService.querylistByOrderId(orderId);
        List<SaleOrderItem> newOrderItemList = new ArrayList<>();
        for (SaleOrderItem paramOrderItem : paramOrderItemList) {
            Double thisQty = paramOrderItem.getThisQty();
            if (thisQty == null || thisQty <= 0) {
                continue;
            }
            for (SaleOrderItem item : orderItemList) {
                if (!(item.getId().equals(paramOrderItem.getId()))) {
                    continue;
                }
                item.setThisQty(paramOrderItem.getThisQty());
                newOrderItemList.add(item);
                break;
            }
        }
        if (newOrderItemList.size() == 0) {
            throw new ServiceException("ORDER-020");
        }
        return newOrderItemList;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void orderPayUpdate(SaleOrder record) throws Exception {
        String formId = "";
        /*小程序发送消息必需字段*/
        if (StringUtils.isNotBlank(record.getFormId())) {
            formId = record.getFormId();
        }
        // 导购助手支付方式
        String type = record.getPayType();
        String loginType = record.getLoginType();
        Double paidInAmount = record.getPaidInAmount();
        if (StringUtils.equals(MP,record.getLoginType())) {
            // 设置支付状态
            record.setPayStatus("Paid");
            record.setIsPaid("Y");
        } else {
            record.setPayStatus("AlreadyPaid");
            //自提订单
            String deliverTypeMerchantPicked = "PICKED_UP";
            SaleOrder saleOrder = new SaleOrder();
            saleOrder = queryById(record.getId());
            //如果订单支付来源来自导购助手会执行销售出库
            if (GUIDE_APP.equals(loginType)) {
                if (deliverTypeMerchantPicked.equals(saleOrder.getDeliverType())) {
                    List<SaleOrderItem> saleOrderItems = saleOrderItemService.querylistByOrderId(saleOrder.getId());
                    //设置出入库的产品数量
                    for (SaleOrderItem item : saleOrderItems) {
                        item.setThisQty(item.getQty());
                    }
                    //库存出库，自提方式自动出库。
                    this.outInInvtxn(saleOrder, saleOrderItems, "salesout");
                }
            }
        }
        saleOrderMapper.orderPayUpdate(record);
        record = saleOrderMapper.queryById(record);
        //支付成功后改变销量
        //查询订单下所有订单行下所有产品改变销量
        SaleOrderItem item = new SaleOrderItem();
        item.setHeadId(record.getId());
        item.setPageFlag(false);
        List<SaleOrderItem> itemList = saleOrderItemService.queryByExamplePage(item);
        for (SaleOrderItem saleOrderItem : itemList) {
            Product product = new Product();
            product.setId(saleOrderItem.getProdId());
            product = productService.queryById(product);
            //如果销量为空的话默认为0
            if (null == product.getCumulateSale()) {
                product.setCumulateSale(0);
            }
            //销量
            Integer cumulateSale = product.getCumulateSale() + saleOrderItem.getQty().intValue();
            product.setCumulateSale(cumulateSale);
            productService.updateCumulateSale(product);

            //如果商品类型为优惠券（Coupon），则进行优惠券发放，如果不是，则不进行发放。
            String prodGoodType = "Coupon";
            if (prodGoodType.equals(product.getProdGoodType())) {
                //发放优惠券
                Account account = new Account();
                account.setId(record.getAcctId());
                List<Account> accountList = accountService.queryByExamplePage(account);
                if (accountList != null && accountList.size() == 1) {
                    account = accountList.get(0);

                    Coupons queryOne = new Coupons();
                    queryOne.setId(product.getCouponId());
                    Coupons coupons = couponsService.queryById(queryOne);

                    String validateOption = coupons.getValidityOption();
                    String fixedDate = "FixedDate";
                    String fixedTerm = "FixedTerm";

                    Long couponId = product.getCouponId();
                    CollectRecord collectRecord = new CollectRecord();
                    collectRecord.setAccntId(account.getId());
                    collectRecord.setCouponsId(couponId);
                    collectRecord.setClaimStatus("Received");
                    collectRecord.setClaimantNum(1);
                    //collectRecord.setReceiveChannel(account.getChannelFrom());
                    collectRecord.setActivityId(coupons.getActivityId());
                    if (fixedDate.equals(validateOption)) {
                        collectRecord.setEffectStaTime(coupons.getEffectStaTime());
                        collectRecord.setEffectEndTime(coupons.getEffectEndTime());
                    } else if (fixedTerm.equals(validateOption)) {
                        Date date = new Date();
                        String nowDate = DateUtil.dateToStr(date, "yyyy-mm-dd");
                        Integer effectDay = coupons.getEffetDay();
                        Date endDate = DateUtil.addDayToDate(date, effectDay);
                        String endDateStr = DateUtil.dateToStr(endDate, "yyyy-mm-dd");

                        collectRecord.setEffectStaTime(nowDate);
                        collectRecord.setEffectEndTime(endDateStr);
                    }
                    collectRecordService.insert(collectRecord);
                }

            }



        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //如果有用优惠券的话，将优惠券状态改为已使用
        if ((record.getCouponsId() != null)
                && record.getAcctId() != null) {
            //小程序提交的订单存储在couponsId里面的是中间表的id
            CollectRecord collectRecord = new CollectRecord();
            collectRecord.setId(record.getCouponsId());
            collectRecord = collectRecordMapper.queryById(collectRecord);
            collectRecord.setClaimStatus("Used");
            //使用时间
            collectRecord.setUseTime(formatter.format(new Date()));
            // 使用人
            collectRecord.setUserId(record.getAcctId());
            collectRecordMapper.update(collectRecord);
            // 更新优惠券已使用数量
            CollectRecord queryOne = new CollectRecord();
            queryOne.setId(record.getCouponsId());
            queryOne = collectRecordMapper.queryById(queryOne);
            Coupons coupons = new Coupons();
            coupons.setId(queryOne.getCouponsId());
            coupons = couponsMapper.queryById(coupons);
            if (coupons.getUsedNum() == null) {
                coupons.setUsedNum(0);
            }
            coupons.setUsedNum(coupons.getUsedNum() + 1);
            couponsService.update(coupons);
        }
        //生成付款记录并改变订单状态
        String cash = "Cash";
        String points = "IntegralPayment";
        if ((StringUtils.equals(record.getPayType(),cash) || StringUtils.equals(record.getPayType(),points)) && !"MP".equals(loginType)) {
            insertPayRecord(record,paidInAmount,loginType);
        }
        String pointsOrCash = "PointsOrCash";
        if (StringUtils.equals(record.getPayType(),pointsOrCash) || "MP".equals(loginType)) {
            // 生成两条cash 和积分
            record.setPayType("Cash");
            insertPayRecord(record,paidInAmount,loginType);

            record.setPayType("IntegralPayment");
            // 积分字段放在paidInAmount 中
            // record.setOrderAmount(paidInAmount);
            insertPayRecord(record,paidInAmount,loginType);
        }
        if (StringUtils.equals(loginType,GUIDE_APP)) {
            record.setPayType(type);
            insertPayRecord(record,paidInAmount,loginType);
        }
        // 根据开关控制是否生成忠诚度交易
        /*String isTran = PropertyUtil.getCropProperty("isTran", record.getCorpid());
        String y = "Y";
        if (StringUtils.equals(y,isTran) && StringUtils.equals(loginType,MP)) {
            this.createTransactionRecord(record);
        }*/
        /*支付完成时，调用生成交易方法*/
        try {
            OrderPaySet params = new OrderPaySet();
            params.setLoginCorpId(record.getCorpid());
            params.setSqlAndCorpId("Y");
            params.setOrderKind(record.getOrderKind());
            params.setOrderFirstType(record.getOrderType());
            params.setOrderSecondType(record.getOrderChildType());
            params.setOrderSource(record.getOrderSource());
            List<OrderPaySet> list = orderPaySetService.queryAll(params);
            if (list != null && list.size() == 1) {
                if ("Y".equals(list.get(0).getCheckTranFlag())) {
                    LCLogger.info().withMessageKey("createTxn").withMessage("调用生成交易方法:" + record.toString()).flush();
                    createTxnAsync(record, true, formId, list.get(0).getSyncFlag());
                }
            }
        } catch (Exception e) {
            LCLogger.info().withMessageKey("createTxn").withMessage(e.getMessage()).flush();
            if ("IntegralOrder".equals(record.getOrderChildType())) {
                throw new ServiceException("ORDER-092");
            }
        }

    }

    /**
     * 生成付款记录
     * @param record
     * @throws Exception
     */
    private void insertPayRecord(SaleOrder record,Double paidInAmount,String loginType) throws Exception {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        PayRecord payRecord = new PayRecord();
        //订单id
        payRecord.setOrderId(record.getId());
        // 付款时间
        payRecord.setPayDate(formatter.format(new Date()));
        // 付款方式 现金 PAY_METHOD
        payRecord.setType(record.getPayType());
        // 付款金额
        if (MP.equals(loginType)) {
            payRecord.setPaySource("MP");
            if ("Cash".equals(record.getPayType())) {
                payRecord.setAmount(String.valueOf(record.getOrderAmount()));
            } else if ("IntegralPayment".equals(record.getPayType())) {
                payRecord.setAmount(String.valueOf(record.getOrderPoints()));
            }
        } else if (GUIDE_APP.equals(loginType)) {
            if (null == record.getPaidInAmount()) {
                record.setPaidInAmount(0.0);
            }
            record.setPaidInAmount(record.getPaidInAmount() + paidInAmount);
            payRecord.setAmount(String.valueOf(paidInAmount));
            payRecord.setPaySource("StoreAPP");
        }
        // 订单编号
        payRecord.setOrderNo(record.getOrderNo());
        // 收款类型，收款或者退款
        payRecord.setPayType("PayIn");
        // 支付状态
        payRecord.setPayStatus("FINISHED");
        // 订单创建人
        payRecord.setOrderCreatedBy(record.getCreatedBy());
        // 订单创建时间
        payRecord.setOrderCreated(record.getCreated());
        //新增付款记录
        payRecordService.insert(payRecord);
        //自提的话改变订单状态为已完成，配送的话改变状态为待发货
        //自提
        String pickedUp = "PICKED_UP";
        //配送
        String mcd = "Merchant distribution";
        if (pickedUp.equals(record.getDeliverType())) {
            // 已完成
            record.setStatus("Closed");
        } else if (mcd.equals(record.getDeliverType())) {
            //代发货
            record.setStatus("Unshipped");
        }
        //修改订单状态
        saleOrderMapper.statusUpdate(record);

    }

    /**
     * 销售排名
     *
     * @param orderSaleRank
     * @return
     */
    @Override
    public OrderSaleRank orderSaleRank(OrderSaleRank orderSaleRank) throws Exception {
        OrderSaleRank result = saleOrderMapper.orderSaleRank(orderSaleRank);
        SalesTarget st = new SalesTarget();
        st.setEmpId(orderSaleRank.getEmpId());
        st.setMonths(orderSaleRank.getRankDate());
        st = salesTargetMapper.queryMonthPlanData(st);
        if (st != null && st.getSaleTargetNum() != null) {
            result.setTargetAmount(Double.toString(st.getSaleTargetNum()));
        } else {
            result.setTargetAmount("0");
        }
        return result;
    }

    /**
     * 销售数据看板
     *
     * @param oad
     * @return
     */
    @Override
    public OrderAmountBoard queryOrderAmountBoard(OrderAmountBoard oad) throws Exception {
        OrderAmountBoard result = new OrderAmountBoard();
        String queryDate = oad.getQueryDate();
        Long orgId = oad.getOrgId();
        OrderAmountBoard orderAB = new OrderAmountBoard();
        orderAB.setQueryDate(queryDate);
        orderAB.setOrgId(orgId);
        //查询月销售实际和订单数
        OrderAmountBoard orderABd = saleOrderMapper.queryOrderAmountBoard(orderAB);
        if (orderABd != null) {
            if (orderABd.getActualAmount() != null) {
                result.setActualAmount(orderABd.getActualAmount());
            } else {
                result.setActualAmount("0");
            }
            if (orderABd.getOrderNum() != null) {
                result.setOrderNum(orderABd.getOrderNum());
            } else {
                result.setOrderNum("0");
            }
        } else {
            result.setActualAmount("0");
            result.setOrderNum("0");
        }
        //上月销售实际和订单数
        OrderAmountBoard orderAB2 = new OrderAmountBoard();
        String lastMonth = oad.getLastMonth();
        orderAB2.setQueryDate(lastMonth);
        orderAB2.setOrgId(orgId);
        OrderAmountBoard orderABd2 = saleOrderMapper.queryOrderAmountBoard(orderAB2);
        if (orderABd2 != null) {
            if (orderABd2.getActualAmount() != null) {
                result.setLastMonthActualAmount(orderABd2.getActualAmount());
            } else {
                result.setLastMonthActualAmount("0");
            }
            if (orderABd2.getOrderNum() != null) {
                result.setLastMonthOrderNum(orderABd2.getOrderNum());
            } else {
                result.setLastMonthOrderNum("0");
            }
        } else {
            result.setLastMonthActualAmount("0");
            result.setLastMonthOrderNum("0");
        }
        //查询月销售目标
        SalesTarget st = new SalesTarget();
        st.setOrgId(orgId);
        st.setMonths(queryDate);
        st = salesTargetMapper.queryMonthPlanData(st);
        if (st != null && st.getSaleTargetNum() != null) {
            result.setTargetAmount(Double.toString(st.getSaleTargetNum()));
        } else {
            result.setTargetAmount("0");
        }
        //上月销售目标
        SalesTarget st2 = new SalesTarget();
        st2.setOrgId(orgId);
        st2.setMonths(lastMonth);
        st2 = salesTargetMapper.queryMonthPlanData(st2);
        if (st2 != null && st2.getSaleTargetNum() != null) {
            result.setLastMonthTargetAmount(Double.toString(st2.getSaleTargetNum()));
        } else {
            result.setLastMonthTargetAmount("0");
        }
        //本月客户数和成交客户数
        GuideReport qReport = new GuideReport();
        qReport.setFilterParm1(queryDate);
        qReport.setFilterParm2(String.valueOf(orgId));
        qReport = guideReportMapper.queryAccntTypeNum(qReport);
        if (qReport != null) {
            if (qReport.getAccntNum() != null) {
                result.setAccntNum(qReport.getAccntNum());
            } else {
                result.setAccntNum("0");
            }
            if (qReport.getClosedAccntNum() != null) {
                result.setClosedAccntNum(qReport.getClosedAccntNum());
            } else {
                result.setClosedAccntNum("0");
            }

        } else {
            result.setAccntNum("0");
            result.setClosedAccntNum("0");
        }
        //上月客户数和成交客户数
        GuideReport qReport2 = new GuideReport();
        qReport2.setFilterParm1(lastMonth);
        qReport2.setFilterParm2(String.valueOf(orgId));
        qReport2 = guideReportMapper.queryAccntTypeNum(qReport2);
        if (qReport2 != null) {
            if (qReport2.getAccntNum() != null) {
                result.setLastMonthAccntNum(qReport2.getAccntNum());
            } else {
                result.setLastMonthAccntNum("0");
            }
            if (qReport2.getClosedAccntNum() != null) {
                result.setLastMonthClosedAccntNum(qReport2.getClosedAccntNum());
            } else {
                result.setLastMonthClosedAccntNum("0");
            }
        } else {
            result.setLastMonthAccntNum("0");
            result.setLastMonthClosedAccntNum("0");
        }
        return result;
    }


    /**
     * 销售业绩看板
     *
     * @param oad
     * @return
     */
    @Override
    public OrderAmountBoard queryMonthAchieveBoard(OrderAmountBoard oad) throws Exception {
        OrderAmountBoard result = new OrderAmountBoard();
        Long orgId = oad.getOrgId();
        //获取查询月及其后六个月
        List<String> searchMonths = new ArrayList<>();
        String currentMonth = oad.getQueryDate();
        String year = currentMonth.substring(0, 4);
        String month = String.valueOf(Integer.parseInt(currentMonth.substring(4)) - 1);
        int six = 6;
        for (int i = 0; i < six; i++) {
            if (month == "12") {
                year = String.valueOf(Integer.parseInt(year) + 1);
                month = "01";
            } else {
                int n = Integer.parseInt(month) + 1;
                if (n < 10) {
                    month = "0" + n;
                } else {
                    month = String.valueOf(n);
                }
            }
            searchMonths.add(year + month);
        }

        List<String> targetList = new ArrayList<String>();
        List<String> actualAmountList = new ArrayList<String>();
        List<String> orderNumList = new ArrayList<String>();
        List<String> closedAccntList = new ArrayList<String>();
        List<String> accntList = new ArrayList<String>();
        List<String> onLineAccntNumList = new ArrayList<String>();
        for (String searchMonth : searchMonths) {
            //查询六个月的销售目标列表
            SalesTarget st = new SalesTarget();
            st.setOrgId(orgId);
            st.setMonths(searchMonth);
            st = salesTargetMapper.queryMonthPlanData(st);
            if (st != null) {
                String stNum = String.valueOf(st.getSaleTargetNum());
                if (stNum != null) {
                    targetList.add(stNum);
                } else {
                    targetList.add("0");
                }
            } else {
                targetList.add("0");
            }
            //查询六个月实际销售列表
            OrderAmountBoard orderAB = new OrderAmountBoard();
            orderAB.setOrgId(orgId);
            orderAB.setQueryDate(searchMonth);
            orderAB = saleOrderMapper.queryOrderAmountBoard(orderAB);
            if (orderAB != null) {
                String acAmount = orderAB.getActualAmount();
                if (acAmount != null) {
                    actualAmountList.add(acAmount);
                } else {
                    actualAmountList.add("0");
                }
            } else {
                actualAmountList.add("0");
            }
            //查询六个月订单数列表
            OrderAmountBoard orderAB2 = new OrderAmountBoard();
            orderAB2.setOrgId(orgId);
            orderAB2.setQueryDate(searchMonth);
            orderAB2 = saleOrderMapper.queryOrderAmountBoard(orderAB2);
            if (orderAB2 != null) {
                String orderNum = orderAB2.getOrderNum();
                if (orderNum != null) {
                    orderNumList.add(orderNum);
                } else {
                    orderNumList.add("0");
                }
            } else {
                orderNumList.add("0");
            }
            //查询六个月成交客户数列表
            GuideReport qt = new GuideReport();
            qt.setFilterParm1(searchMonth);
            qt.setFilterParm2(String.valueOf(orgId));
            qt = guideReportMapper.queryAccntTypeNum(qt);
            if (qt != null) {
                String closedAt = qt.getClosedAccntNum();
                if (closedAt != null) {
                    closedAccntList.add(closedAt);
                } else {
                    closedAccntList.add("0");
                }
            } else {
                closedAccntList.add("0");
            }
            //查询六个月新增客户数列表
            GuideReport qt2 = new GuideReport();
            qt2.setFilterParm1(searchMonth);
            qt2.setFilterParm2(String.valueOf(orgId));
            qt2 = guideReportMapper.queryAccntTypeNum(qt2);
            if (qt2 != null) {
                String atNum = qt2.getAccntNum();
                if (atNum != null) {
                    accntList.add(atNum);
                } else {
                    accntList.add("0");
                }
            } else {
                accntList.add("0");
            }
            //查询六个月线上沟通客户人次
            GuideReport qt3 = new GuideReport();
            qt3.setFilterParm1(searchMonth);
            qt3.setFilterParm2(String.valueOf(orgId));
            qt3 = guideReportMapper.queryOnLineAccntNum(qt3);
            if (qt3 != null) {
                String olAccntNum = qt3.getOnLineAccntNum();
                if (olAccntNum != null) {
                    onLineAccntNumList.add(olAccntNum);
                } else {
                    onLineAccntNumList.add("0");
                }
            } else {
                onLineAccntNumList.add("0");
            }
        }
        //查询销售目标累计
        if (targetList != null) {
            double salesTargetSum = 0;
            for (String item : targetList) {
                salesTargetSum += Double.parseDouble(item);
            }
            result.setTargetAmountSum(String.valueOf(salesTargetSum));
        }
        //查询实际销售累计
        if (actualAmountList != null) {
            double actualAmountSum = 0;
            for (String item : actualAmountList) {
                actualAmountSum += Double.parseDouble(item);
            }
            result.setActualAmountSum(String.valueOf(actualAmountSum));
        }
        //查询订单数累计
        if (orderNumList != null) {
            double orderNum = 0;
            for (String item : orderNumList) {
                orderNum += Double.parseDouble(item);
            }
            result.setOrderNumSum(String.valueOf(orderNum));
        }
        //查询客户数累计
        if (accntList != null) {
            double accntSum = 0;
            for (String item : accntList) {
                accntSum += Double.parseDouble(item);
            }
            result.setAccntNumSum(String.valueOf(accntSum));
        }
        result.setTargetAmountList(targetList);
        result.setActualAmountList(actualAmountList);
        result.setOrderNumList(orderNumList);
        result.setAccntNumList(accntList);
        result.setClosedAccntNumList(closedAccntList);
        result.setOnLineAccntNumList(onLineAccntNumList);

        return result;
    }


    /**
     * 企点新建订单
     */
    @Override
    public void insertGuideOrder(SaleOrder record) throws Exception {
        saleOrderMapper.guideOrderInsert(record);
    }

    /**
     * 提交订单
     **/
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public SaleOrder commitOrder(SaleOrder record) throws Exception {

        if (record == null) {
            throw new BasicDaoException("订单信息不能为空!");
        }
        // 订单id
        Long orderId = record.getId();
        //手机号
        String phone = record.getContactTel();
        // 订单编号
        String orderNo = record.getOrderNo();

        if (orderId == null) {
            record.setId(keyGenerateService.keyGenerate());
        }
        if (StringUtils.isBlank(orderNo)) {
//            record.setOrderNo(record.getId().toString());
            record.setOrderNo(generateCodeSingleton.getOrderCodeStr());
        }

        SaleOrder qo = new SaleOrder();
        String newStatus = "NEW";
        if (!newStatus.equals(record.getRow_status())) {
            qo = queryById(record);
        } else {
            qo = record;
        }
        /*如果订单状态为空,或者订单状态为新建,则将其置为已提交*/
        String newStr = "New";
        if (StringUtils.isBlank(qo.getStatus()) || newStr.equals(qo.getStatus())) {
            // 修改订单状态为'已提交'
            record.setStatus("Submitted");
            // 设置提交时间
            record.setSubmitDate(DateUtil.dateToStr(new Date(), "yyyy-MM-dd"));
        } else {
            throw new BasicDaoException("该订单已经提交,请勿重复提交!");
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String mp = "MP";
        String nFlag = "N";
        //登陆类型：小程序
        if (StringUtils.equals(mp,record.getLoginType())) {
            // 查询默认价格表
            CoreUser loginUser = UserUtil.getUser();
            loginUser.setId(loginUser.getAcctId());
            PriceListItem item = new PriceListItem();
            item.setLoginCorpId(loginUser.getLoginCorpId());
            item.setHeadId(UserUtil.getUser().getPriceListId());
            Double totalAmount = 0.0;
            for (SaleOrderItem saleOrderItem : record.getSaleOrderItemList()) {
                // 查询价格表下对应产品信息
                item.setProdId(saleOrderItem.getProdId());
                List<PriceListItem> list = priceListItemService.queryByProdId(item);
                if (list != null && list.size() > 0) {
                    PriceListItem plItem = list.get(0);
                    Double promoPrice = plItem.getPromoPrice();
                    if (promoPrice != null && saleOrderItem.getQty() != null) {
                        totalAmount += promoPrice * saleOrderItem.getQty();
                    }
                }
            }
            record.setOrderTotalAmount(totalAmount);

            CollectRecord collectRecord = new CollectRecord();
            collectRecord.setId(record.getCouponsId());
            collectRecord = collectRecordMapper.queryById(collectRecord);
            if (null != collectRecord) {
                //判断优惠券是否有效
                Date timeNow = new Date();
                String timeStr = collectRecord.getEffectEndTime();
                if (StringUtils.isNotBlank(timeStr)) {
                    Date timeEnd = DateUtil.stringToDate(timeStr, "yyyy-MM-dd HH:mm:ss");
                    if (timeNow.after(timeEnd)) {
                        throw new Exception("优惠券已经失效，请重新选择");
                    }
                }
                // 判断优惠券是否已经被使用
                String locked = "Locked";
                String received = "Received";
                if (!StringUtils.equals(received,collectRecord.getClaimStatus())) {
                    throw new Exception("优惠券无法使用，请重新选择优惠券");
                }
                Double disAo = record.getActualCutPrice();
                Double orderAmount = record.getOrderTotalAmount() - disAo;
                if (orderAmount < 0) {
                    orderAmount = 0.0;
                    //如果订单总额小于优惠金额,优惠金额取订单总额
                    disAo = record.getOrderTotalAmount();
                }
                record.setOrderAmount(orderAmount);
                record.setOrderDiscount(disAo);
                // 添加使用优惠券记录
                String nowTimeStr = DateUtil.dateToStr(timeNow, "yyyy-MM-dd HH:mm:ss");
                collectRecord.setId(collectRecord.getId());
                collectRecord.setClaimStatus(locked);
                collectRecord.setUseChannel("MiniProgram");
                collectRecord.setClaimTime(formatter.format(new Date()));
                collectRecord.setUseTime(nowTimeStr);
                collectRecord.setUserId(record.getAcctId());
                collectRecordMapper.update(collectRecord);

            } else {
                //设置订单金额
                record.setOrderAmount(record.getOrderTotalAmount());
            }
            if (StringUtils.equals(newStatus,record.getRow_status())) {
                // 新建订单头
                record.setPriceListId(UserUtil.getUser().getPriceListId());
                this.insert(record);
                // 创建订单行
                for (SaleOrderItem saleOrderItem : record.getSaleOrderItemList()) {
                    saleOrderItem.setId(keyGenerateService.keyGenerate());
                    saleOrderItem.setHeadId(record.getId());
                    // 查询价格表下对应产品信息
                    item.setProdId(saleOrderItem.getProdId());
                    List<PriceListItem> list = priceListItemService.queryByProdId(item);
                    if (list != null && list.size() > 0) {
                        PriceListItem plItem = list.get(0);
                        saleOrderItem.setBasePrice(plItem.getPrice());
                        saleOrderItem.setPromotionPrice(plItem.getPromoPrice());
                        saleOrderItem.setBasePoints(plItem.getPoint());
                        if (saleOrderItem.getBasePoints() != null && saleOrderItem.getQty() != null) {
                            saleOrderItem.setTotalItemPoints(saleOrderItem.getBasePoints() * saleOrderItem.getQty());
                        }
                    }
                    saleOrderItemService.insert(saleOrderItem);
                    //订单来源为购物车时删除购物车里面相应记录
                    if ("ShopCart".equals(record.getSubmitSource())) {
                        ShopCart shopCart = new ShopCart();
                        shopCart.setId(Long.parseLong(saleOrderItem.getAttr1()));
                        shopCart = shopCartService.queryById(shopCart);
                        if (null != shopCart && !"Y".equals(shopCart.getTbIsDelete())) {
                            shopCart.setTbIsDelete("Y");
                            shopCartService.update(shopCart);
                        }
                    }
                }
            } else {
                update(record);
            }
        } else {
            //核销优惠券
            //判断优惠券是否有效
            //获取同一个手机号下 多个消费者
            List<Long> acctIdList = null;
            if (StringUtils.isNotBlank(phone)) {
                Account account = new Account();
                account.setMobilePhone1(phone);
                account.setPageFlag(false);
                List<Account> accountList = accountMapper.queryByExamplePage(account);
                if (accountList.size() > 0) {
                    acctIdList = new ArrayList<>(16);
                    for (Account bean : accountList) {
                        acctIdList.add(bean.getId());
                    }
                }
            }
            Coupons coupons = new Coupons();
            coupons.setId(record.getCouponsId());
            coupons = couponsMapper.queryById(coupons);
            if (null != coupons && nFlag.equals(coupons.getIsEffect())) {
                throw new Exception("优惠券已经失效，请重新选择");
            }
            CollectRecord collectRecord = new CollectRecord();
            collectRecord.setCouponsId(record.getCouponsId());
            collectRecord.setPageFlag(false);
            String received = "Received";
            collectRecord.setAcctIdList(acctIdList);
            //同一个券 多个渠道领取 多个记录 (同一个手机号）
            List<CollectRecord> collectRecords = collectRecordMapper.queryByExamplePage(collectRecord);
            if (record.getCouponsId() != null && collectRecords.size() > 0) {
                CollectRecord cRecord = collectRecords.get(0);
                if (!received.equals(cRecord.getClaimStatus())) {
                    throw new Exception("优惠券无法使用，请重新选择优惠券");
                }
                cRecord.setClaimTime(formatter.format(new Date()));
                //使用时间
                cRecord.setUseTime(formatter.format(new Date()));
                cRecord.setUserId(record.getAcctId());
                //使用渠道导购助手app
                cRecord.setUseChannel("Guide");
                // 优惠券状态：已锁定
                cRecord.setClaimStatus("Locked");
                collectRecordService.update(cRecord);
                // 设置中间表id为订单上的优惠券id
                record.setCouponsId(cRecord.getId());
            }
            if (newStatus.equals(record.getRow_status())) {
                // 新建订单头
                insertGuideOrder(record);
                // 创建订单行
                for (SaleOrderItem saleOrderItem : record.getSaleOrderItemList()) {
                    saleOrderItem.setId(keyGenerateService.keyGenerate());
                    saleOrderItemService.insert(saleOrderItem);
                }
            } else {
                update(record);
            }
        }
        /*
         * 订单提交成功跟变客户状态为OrderConsumer
         * */
        Account acct = new Account();
        if (record.getAcctId() != null) {
            acct = accountService.queryById(record.getAcctId());
            if (!"OrderConsumer".equals(acct.getAcctStage())) {
                acct.setAcctStage("OrderConsumer");
                accountService.update(acct);
            }
        }
        // 汇总应付金额和消耗积分
        SaleOrder saleOrder = saleOrderMapper.queryById(record);
        SaleOrderItem saleOrderItem = new SaleOrderItem();
        saleOrderItem.setHeadId(record.getId());
        saleOrderItem.setPageFlag(false);
        List<SaleOrderItem> saleOrderItems = saleOrderItemService.queryByExamplePage(saleOrderItem);
        Double orderTotalAmount = 0.0;
        Double orderPoints = 0.0;
        for (SaleOrderItem item : saleOrderItems) {
            if (item.getPromotionPrice() != null && item.getQty() != null) {
                orderTotalAmount += item.getPromotionPrice() * item.getQty();
            }
            if (item.getTotalItemPoints() != null) {
                orderPoints += item.getTotalItemPoints();
            }
        }
        saleOrder.setOrderTotalAmount(orderTotalAmount);
        saleOrder.setOrderPoints(orderPoints);
        update(saleOrder);
        // saleOrder.setSaleOrderItemList(saleOrderItems);
        return saleOrder;
    }


    /**
     * 查询订单列表-同时查询出各订单的产品列表
     *
     * @author Song
     * 2017年0426
     */
    @Override
    public List<SaleOrder> queryByExamplePage(SaleOrder ob) throws Exception {
        List<SaleOrder> list = saleOrderMapper.queryByExamplePage(ob);
        String yFlag = "Y";
        // 在未登录时，模拟登录处理逻辑
        if (GUIDE_APP.equals(ob.getLoginType()) || MP.equals(ob.getLoginType())
                || DMS_APP.equals(ob.getLoginType()) || yFlag.equals(ob.getImitateLogin())) {
            //查询订单产品列表
            for (SaleOrder l : list) {
                SaleOrderItem op = new SaleOrderItem();
                op.setHeadId(l.getId());
                op.setPageFlag(false);
                List<SaleOrderItem> prodList = saleOrderItemService.queryByExamplePage(op);
                l.setSaleOrderItemList(prodList);
            }

        }
        return list;
    }

    /**
     * 查询订单明细
     *
     * @author Song
     * 20170426
     */
    @Override
    public SaleOrder queryById(SaleOrder ob) throws Exception {
        SaleOrder order = saleOrderMapper.queryById(ob);
        if (GUIDE_APP.equals(ob.getLoginType())) {
            //查询订单产品列表
            SaleOrderItem op = new SaleOrderItem();
            op.setPageFlag(false);
            op.setHeadId(order.getId());
            List<SaleOrderItem> prodList = saleOrderItemService.queryByExamplePage(op);
            order.setSaleOrderItemList(prodList);
        }
        return order;
    }

    /**
     * 查询所有的订单列表
     *
     * @author Lizt
     * 2017年0508
     */
    @Override
    public List<SaleOrder> queryAll(SaleOrder ob) throws Exception {
        ob.setPageFlag(false);
        List<SaleOrder> list = saleOrderMapper.queryByExamplePage(ob);
        if (GUIDE_APP.equals(ob.getLoginType())) {
            //查询订单产品列表
            for (SaleOrder l : list) {
                SaleOrderItem op = new SaleOrderItem();
                op.setHeadId(l.getId());
                op.setPageFlag(false);
                List<SaleOrderItem> prodList = saleOrderItemService.queryByExamplePage(op);
                l.setSaleOrderItemList(prodList);
            }
        }
        return list;
    }

    @Override
    public int queryPurchaseMoreByAccntIdCount(SaleOrder record) throws Exception {
        return saleOrderMapper.queryPurchaseMoreByAccntIdCount(record);
    }

    @Override
    public List<Product> queryPurchaseMoreByAccntId(SaleOrder record)
            throws Exception {
        return saleOrderMapper.queryPurchaseMoreByAccntId(record);
    }

    /**
     * dms订单的提交，如果订单不存在则先新建订单
     * 前端需要传过来订单状态，如果传过来的订单还未新建则设置dataOperationType为"new"
     *
     * @param record
     * @throws Exception
     * @auhtor lizt 20180522
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void commitDmsOrder(SaleOrder record) throws Exception {
        CoreUser user = UserUtil.getUser();
        String newStr = "NEW";
        if (newStr.equals(record.getRow_status())) {
            record.setStatus("New");
        }
        String submitType = record.getRow_status();
        String rejected = "Rejected";
        //校验订单状态
        if (!StringUtils.equals(submitType, newStr) && !StringUtils.equals(submitType, rejected)) {
            throw new ServiceException("ORDER-029");
        }
        //插入或者更新订单
        record.setStatus("Submitted");
        Long orderId = record.getId();
        if (orderId == null) {
            orderId = keyGenerateService.keyGenerate();
            record.setId(orderId);
        }
//        upsertDmsOrder(record);
        upsertHeadAndLine(record);
        String salesOrder = "SalesOrder";
        //如果是采购订单，则计算返利金额字段并清空购物车
        if (salesOrder.equals(record.getOrderType())) {
            //根据客户上的返利百分比计算返利金额，并保存在订单头信息上
            SaleOrder order = saleOrderMapper.queryById(record);
            Double orderTotalAmount = order.getOrderTotalAmount();
            Account accounts = new Account();
            accounts.setId(user.getAcctId());
            accounts = accountService.queryById(accounts);
            Double rebatePercent = accounts.getRebatePercent();
            Double rebateMoney = (orderTotalAmount == null ? 0.0 : orderTotalAmount) * (rebatePercent == null ? 0.0 : rebatePercent);
            order.setRebateMoney(rebateMoney);
            order.setCash(orderTotalAmount - rebateMoney);
            order.setFreight(0.0);
//            orderMapper.commitDmsOrder(order);
            saleOrderMapper.update(order);
            String shopCartStr = "shopCart";
            // 如果为购物车提交，则删除购物车
            if (shopCartStr.equals(submitType)) {
                ShopCart shopCart = new ShopCart();
                shopCart.setAttr1(String.valueOf(order.getId()));
                shopCartService.deleteByOrderId(shopCart);
            }
        }
    }

    @Override
    public void orderStatusUpdateByPayRecord(PayRecord entity) throws Exception {
        SaleOrder saleOrder = queryOneById(entity.getOrderId());
        List<SaleOrderItem> saleOrderItems = saleOrderItemService.querylistByOrderId(entity.getOrderId());
        if (saleOrder == null) {
            throw new ServiceException("ORDER-054",entity.getOrderId().toString());
        }
        if (saleOrder.getOrderTotalAmount() == null) {
            throw new ServiceException("ORDER-080",saleOrder.getOrderNo());
        }
        PayRecord queryParam = new PayRecord();
        queryParam.setPageFlag(false);
        queryParam.setHeadId(entity.getOrderId());
        queryParam.setOrderId(entity.getOrderId());
        List<PayRecord> payRecordList = payRecordMapper.queryByExamplePage(queryParam);
        Double sum = payRecordList.stream()
                .mapToDouble(p -> Double.parseDouble(p.getAmount()))
                .sum();
        //保留两位有效小数
        int decimalPlace = 2;
        sum = BigDecimal.valueOf(sum).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).doubleValue();
        Double payOutSum = payRecordList.stream()
                .filter(f -> "PayOut".equals(f.getPayType()))
                .filter(f -> "FINISHED".equals(f.getPayStatus()))
                .mapToDouble(p -> Math.abs(Double.parseDouble(p.getAmount())))
                .sum();
        //新增每条支付记录将修改订单的实付金额
        saleOrder.setPaidInAmount(sum);
        saleOrderMapper.paidinUpdate(saleOrder);
//        String payBalanceSuccess = "0";
        String deliverTypeMerchant = "Merchant distribution";
        String deliverTypeMerchantPicked = "PICKED_UP";
        String payIn = "PayIn";
        String payOut = "PayOut";
        String deliverType = saleOrder.getDeliverType();
        if (deliverType == null) {
            throw new ServiceException("ORDER-081",entity.getOrderId().toString());
        }
        if (payIn.equals(entity.getPayType())) {
            if (sum.equals(saleOrder.getOrderTotalAmount())) {
                if (deliverTypeMerchantPicked.equals(deliverType)) {
                    //设置出入库的产品数量
                    for (SaleOrderItem item : saleOrderItems) {
                        item.setThisQty(item.getQty());
                    }
                    //库存出库，自提方式自动出库。
                    this.outInInvtxn(saleOrder, saleOrderItems, "salesout");
                    saleOrder.setStatus("Closed");
                }
                if (deliverTypeMerchant.equals(deliverType)) {
                    saleOrder.setStatus("Unshipped");
                }
                saleOrder.setPayStatus("AlreadyPaid");
                orderStatusUpdate(saleOrder);
            } else {
                saleOrder.setStatus("Submitted");
                saleOrder.setPayStatus("Unpaid");
                orderStatusUpdate(saleOrder);
//            if (sum == 0) {
//                saleOrder.setStatus("Submitted");
//                saleOrder.setPayStatus("Unpaid");
//                orderStatusUpdate(saleOrder);
//            } else if (sum < saleOrder.getOrderTotalAmount() && sum > 0) {
//                saleOrder.setStatus("Submitted");
//                saleOrder.setPayStatus("AlreadyPaid");
//                orderStatusUpdate(saleOrder);
//            } else {
//                throw new Exception("订单编号为" + saleOrder.getOrderNo() + "的订单付款记录异常,请查证后再试!");
//            }
            }
        } else if (payOut.equals(entity.getPayType())) {
            if (payOutSum.equals(saleOrder.getOrderTotalAmount())) {
                saleOrder.setPayStatus("Refunded");
                this.orderStatusUpdate(saleOrder);
            }
        }

        /*支付完成时，调用生成交易方法*/
        try {
            OrderPaySet params = new OrderPaySet();
            params.setLoginCorpId(saleOrder.getCorpid());
            params.setSqlAndCorpId("Y");
            params.setOrderKind(saleOrder.getOrderKind());
            params.setOrderFirstType(saleOrder.getOrderType());
            params.setOrderSecondType(saleOrder.getOrderChildType());
            params.setOrderSource(saleOrder.getOrderSource());
            List<OrderPaySet> list = orderPaySetService.queryAll(params);
            if (list != null && list.size() == 1) {
                if ("Y".equals(list.get(0).getCheckTranFlag())) {
                    LCLogger.info().withMessageKey("createTxn").withMessage("调用生成交易方法:" + saleOrder.toString()).flush();
                    createTxnAsync(saleOrder, true, saleOrder.getFormId(), list.get(0).getSyncFlag());
                }
            }
        } catch (Exception e) {
            LCLogger.info().withMessageKey("createTxn").withMessage(e.getMessage()).flush();
        }
    }

    /**
     * 校验所扫描得到优惠券是否可以使用
     *
     * @param saleOrder
     * @return map
     * @throws Exception
     */
    @Override
    public Map<String, Object> couponsCheckOrder(SaleOrder saleOrder) throws Exception {
        Map<String, Object> map = new HashMap<>(8);
        //获取到优惠领取人的客户id
        Long acctId = Long.parseLong(saleOrder.getAttr7());
        Coupons coupons = new Coupons();
        coupons.setAccntId(acctId);
        //当前时间在优惠券有效日期之内,是否有效
        coupons.setIsEffect("Y");
        //排查失效的券
        coupons.setAttr1("effective");
        //优惠券id
        coupons.setId(saleOrder.getCouponsId());
        List<Coupons> couponsList = couponsMapper.queryByExamplePage(coupons);
        if (couponsList.size() == 0) {
            throw new Exception("您所使用的优惠券已经失效，请选择其他优惠券");
        }
        coupons = couponsList.get(0);
        //查询记录表中优惠券使用情况
        CollectRecord record = new CollectRecord();
        record.setCouponsId(saleOrder.getCouponsId());
        record.setAccntId(acctId);
        record.setPageFlag(false);
        List<CollectRecord> recordList = collectRecordMapper.queryByCollectRecordExamplePage(record);
        if (recordList.size() > 0) {
            record = recordList.get(0);
            String status = "Used";
            if (status.equals(record.getClaimStatus())) {
                throw new Exception("您所使用的优惠券已经使用过不能重复使用");
            }
        }
        //判断优惠券是否使用订单里面的其中某一个产品
        List<SaleOrderItem> itemList = saleOrder.getSaleOrderItemList();
        Boolean success = false;
        // 满足使用优惠券的产品总价
        Double amount = 0.0;
        for (SaleOrderItem saleOrderItem : itemList) {
            Product product = new Product();
            product.setId(saleOrderItem.getProdId());
            product.setPriceListId(saleOrder.getPriceListId());
            product = productMapper.queryById(product);
            product.setAcctId(acctId);
            //产品适用优惠券
            List<Coupons> list = (List<Coupons>) couponsService.productForCard(product).get("rows");
            for (Coupons coups : list) {
                if (coupons.getId().equals(coups.getId())) {
                    success = true;
                    Double salePrice = saleOrderItem.getNetPrice();
                    amount = amount + salePrice;
                    break;
                }
            }
        }
        if (!success) {
            throw new Exception("您的优惠券不适用于您的订单");
        }
        //查询最低使用金额
        int amountLimit = coupons.getAmountLimit();
        if (amountLimit > amount) {
            throw new Exception("订单金额未到达优惠券最低使用金额");
        }
        map.put("rows", coupons);
        return map;
    }

    @Override
    public void collectRecordUpdate(SaleOrder record) throws Exception {
        //查询订单详情
        record = saleOrderMapper.queryById(record);
        CollectRecord collectRecord = new CollectRecord();
        //查询出领取记录记录
        CollectRecord collectR = new CollectRecord();
        collectR.setId(record.getCouponsId());
        collectRecord = collectRecordMapper.queryById(collectR);
        if (collectRecord != null) {
            collectRecord.setClaimStatus("Received");
            collectRecordMapper.update(collectRecord);
        }
    }

    /**
     * 订单取消后改变已经使用过的优惠券为未使用状态
     *
     * @param record
     * @throws Exception
     * @author 路江
     */
    @Override
    public void couponsUpdateStatus(SaleOrder record) throws Exception {
        SaleOrder saleOrder = new SaleOrder();
        saleOrder.setId(record.getId());
        saleOrder = queryById(saleOrder);
        if (saleOrder.getCouponsId() != null) {
            //导购助手app
            CollectRecord collectRecord = new CollectRecord();
            //小程序类订单记录里存的couponsId为领取记录的id
            collectRecord.setId(saleOrder.getCouponsId());
            collectRecord = collectRecordMapper.queryById(collectRecord);
            //设置为已领取，未使用
            collectRecord.setClaimStatus("Received");
            collectRecordMapper.update(collectRecord);
        }
    }


    @Override
    public Map<String, Object> queryOrder() throws Exception {
        //查询15分钟之前到现在还没有付款的订单
        Map<String, Object> map = new HashMap<>(8);
        //取参数配置里面的参数：多少分钟之内  先设置为15min
        Integer ntime = 15;
        Integer stime = ntime + 5;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 20分钟之前
        Date startDate = DateUtil.addMinuteToDate((new Date()),-stime);
        String startTime = format.format(startDate);
        // 15分钟前
        Date endDate = DateUtil.addMinuteToDate((new Date()),-ntime);
        String endTime = format.format(endDate);
        SaleOrder saleOrder = new SaleOrder();
        // 开始时间
        saleOrder.setAttr1(startTime);
        // 结束时间
        saleOrder.setAttr2(endTime);
        saleOrder.setPayStatus("Unpaid");
        //类型为小程序订单和导购助手app订单
        List<SaleOrder> saleOrders = saleOrderMapper.queryUnpaidOrder(saleOrder);
        //设置订单状态为已取消
        for (SaleOrder order :saleOrders) {
            order.setStatus("Cancelled");
            saleOrderMapper.statusUpdate(order);
            updateCouponsStatus(order);

        }
        return map;
    }

    /**
     * 改变优惠券状态
     * @param order
     * @throws Exception
     */
    private void updateCouponsStatus(SaleOrder order) throws  Exception {
        // 订单里面的couponsId 即为领取记录表的id
        if (order.getCouponsId() == null) {
            CollectRecord record = new CollectRecord();
            record.setId(order.getCouponsId());
            record = collectRecordMapper.queryById(record);
            record.setClaimStatus("Received");
            collectRecordMapper.update(record);
        }
    }

    /**
     * 校验是否过期
     * @param saleOrder
     * @return map
     * @throws Exception
     */
    @Override
    public Map<String, Object> checkOrderStatus(SaleOrder saleOrder) throws Exception {
        Map<String, Object> map = new HashMap<>(8);
        Integer time = 15;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        saleOrder = saleOrderMapper.queryById(saleOrder);
        Date startDate = DateUtil.addMinuteToDate((new Date()),-time);
        Date created = format.parse(saleOrder.getCreated());
        //订单状态 未支付
        if (null == saleOrder.getPayStatus() && created.getTime() < startDate.getTime()) {
            // 将订单状态设置为已取消
            saleOrder.setStatus("Cancelled");
            saleOrderMapper.statusUpdate(saleOrder);
            updateCouponsStatus(saleOrder);
            throw new ServiceException("ORDER-079");
        }
        return map;
    }

    @Override
    public void createTransactionRecord(SaleOrder record) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Transaction transaction = new Transaction();
        // 交易生成的时间
        transaction.setTransactionDate(format.format(new Date()));
        // 交易的子类型  LYT_TXN_SUB_TYPE
        String cash = "Cash";
        String points = "IntegralPayment";
        if (StringUtils.equals(record.getPayType(),cash)) {
            transaction.setTransactionSubType("PurchaseProduct");
        } else if (StringUtils.equals(record.getPayType(),points)) {
            transaction.setTransactionSubType("PointExchange");
        }
        // 交易的状态  LYT_TXN_STATUS
        transaction.setStatus("Submitted");
        // 交易支付的金额
        transaction.setAmount(record.getOrderAmount());
        if (StringUtils.equals(String.valueOf(transaction.getAmount()),"null")) {
            transaction.setAmount(null);
        }
        // 积分
        transaction.setPoints(record.getOrderPoints());
        if (StringUtils.equals(String.valueOf(transaction.getPoints()),"null")) {
            transaction.setPoints(null);
        }
        // 订单id
        transaction.setOrderId(record.getId());
        // 项目id
        // 查询对应的忠诚度项目
        Long mallLytProgramId = Long.parseLong(PropertyUtil.getCropProperty("mallLoyalProgramId", record.getCorpid()));
        LytMember member = new LytMember();
        member.setAccountId(record.getAcctId());
        member.setProgramId(mallLytProgramId);
        Map<String, Object> mapArg = new HashMap<>(16);
        Map<String, Object> memberRet = memberClient.queryByExamplePage(member);
        if (!(boolean)memberRet.get("success")) {
            throw new ServiceException((String) memberRet.get("result"));
        }
        List<Member> memberList = (List<Member>) memberRet.get("result");
        if (memberList.size() > 0) {
            transaction.setMemberId(memberList.get(0).getId());
            // 合作方id
            transaction.setPartnerId(memberList.get(0).getPartnerId());
        }
        transaction.setProgramId(mallLytProgramId);
        // 生成忠诚度交易
        Map<String, Object> transactionRet = transactionClient.insert(transaction);
        if (!(boolean) transactionRet.get("success")) {
            throw new ServiceException((String) transactionRet.get("result"));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SaleOrder deepCopyDmsOrder(SaleOrder order) {
        try {
            CoreUser user = UserUtil.getUser();
            Long acctId = user.getAcctId();
            if (acctId == null) {
                throw new ServiceException("ORDER-082");
            }
            if (order.getId() == null) {
                throw new ServiceException("ORDER-007");
            }
            SaleOrder saleOrder = new SaleOrder();
            saleOrder.setId(order.getId());
            saleOrder = this.queryById(saleOrder);
            if (saleOrder == null) {
                throw new ServiceException("ORDER-054",order.getId().toString());
            }
            Long orderId = keyGenerateService.keyGenerate();
            saleOrder.setId(orderId);
            saleOrder.setAcctId(acctId);
            Account account = new Account();
            account.setId(acctId);
            //确认系统中确实有此客户才允许新建
            account = accountService.queryById(account);
            if (account == null) {
                throw new ServiceException("ORDER-050",acctId.toString());
            }
            String dealerOrder = "DealerOrder";
            //如果是创建销售订单查询产品
            if (dealerOrder.equals(order.getOrderKind())) {
                Long orgId = acctId;
                //校验组织
                Orgnization org = orgnizationService.queryById(orgId);
                if (org == null) {
                    throw new ServiceException("PUBLIC-055");
                }
                Long priceListId = org.getPriceListId();
                if (priceListId == null) {
                    //价格表id
                    saleOrder.setPriceListId(priceListId);
                } else {
                    throw new ServiceException("ORDER-082");
                }
            } else {
                //价格表id
                saleOrder.setPriceListId(account.getPriceListId());
            }
            saleOrder.setOrgId(account.getOrgId());
//            saleOrder.setOrderNo(saleOrder.getId().toString());
            saleOrder.setOrderNo(generateCodeSingleton.getOrderCodeStr());
            saleOrder.setStatus("New");
            saleOrder.setOrderType(order.getOrderType());
            saleOrder.setIsPaid("N");
            // 取当前时间
            saleOrder.setOrderDate(null);
            // 不复制订单提交时间
            saleOrder.setSubmitDate(null);

            if (StringUtils.isBlank(saleOrder.getOrderType())) {
                //默认销售订单
                saleOrder.setOrderType("SalesOrder");
                saleOrder.setOrderTypeLovType("SalesOrder");
            }
            this.insert(saleOrder);
            String salesOrder = "SalesOrder";
            if (salesOrder.equals(saleOrder.getOrderType())) {
                //销售订单应用政策
                SaleOrderItem t = new SaleOrderItem();
                t.setHeadId(order.getId());
                t.setAttr4("Common Item");
                t.setPageFlag(false);
                //查询非赠品订单行
                List<SaleOrderItem> list = saleOrderItemService.queryByExamplePage(t);
                Long acctOrgId = user.getOrgId();
                saleOrderItemService.insertDmsOrderItem(acctOrgId, null, orderId, list);
                SaleOrderItem example = new SaleOrderItem();
                example.setPageFlag(false);
                example.setHeadId(order.getId());
                List<SaleOrderItem> items = saleOrderItemService.queryByExamplePage(example);
                saleOrder.setSaleOrderItemList(items);
                policyService.getPolicy(saleOrder);
            } else {
                //非销售订单则直接复制原订单行，如退货单
                saleOrderItemService.deepCopyOrderItem(order.getId(), orderId);
            }
            return saleOrder;
        } catch (ServiceException e) {
            LCLogger.withException(e);
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("ORDER-083");
        }
    }

    /**
     * 是否同步创建交易
     * @author zhuboyang
     * @date 2019-09-10 21:03
     * @param saleOrder 订单数据
     * @param registerFlag 应计偿还标记
     * @param syncFlag 是否同步创建交易
     * @return void
     */
    private void createTxnAsync(SaleOrder saleOrder, boolean registerFlag,String formId, String syncFlag) throws Exception {
        if ("N".equals(syncFlag)) {
            linkThreadPoolExecutor.execute(() -> {
                try {
                    //异步执行交易
                    LCLogger.info().withMessage("========异步执行交易开始==========");
                    createTxn(saleOrder, registerFlag, formId);
                    LCLogger.info().withMessage("========异步执行交易结束==========");
                } catch (Exception e) {
                    LCLogger.error().withMessageKey("订单生成交易异常：")
                            .withMessage("订单号:" + saleOrder.getOrderNo() + "; 异常信息:" + e.getMessage()).flush();
                }
            });
        } else {
            createTxn(saleOrder, registerFlag, formId);
        }
    }

    /**
     * 创建交易
     *
     * @author NingLanhao
     * @date 2019-07-22 21:03
     * @param saleOrder 订单数据
     * @param registerFlag 应计偿还标记
     * @return void
     */
    private void createTxn(SaleOrder saleOrder, boolean registerFlag, String formId) throws Exception {
        // 创建交易前查询是否存在会员
        LytMember memberArg = new LytMember();
        memberArg.setStayFields("id,programId,partnerId");
        memberArg.setAccountId(saleOrder.getAcctId());
        Map<String, Object> memberRet = memberClient.queryByExamplePage(memberArg);
        if (!(boolean)memberRet.get("success")) {
            throw new ServiceException((String) memberRet.get("rows"));
        }
        List<JSONObject> memberList = (List<JSONObject>) memberRet.get("rows");
        Member member = new Member();
        if (memberList.size() > 0) {
            /*根据原有查询逻辑，目前列表有且仅有一条记录*/
            member = JSON.parseObject(JSON.toJSONString(memberList.get(0)), Member.class);
        } else {
            // 取客户的手机号，找到对应的会员
            Account account = accountService.queryById(saleOrder.getAcctId());
            if (account != null) {
                LytMember member1 = new LytMember();
                member1.setMobilePhone(account.getMobilePhone1());
                String lytDefaultProgramId = PropertyUtil.getProperty("lytDefaultProgramId", account.getCorpid());
                member1.setProgramId(Long.parseLong(lytDefaultProgramId));
                Map<String, Object> memberRet1 = memberClient.queryByExamplePage(member1);
                if (!(boolean)memberRet.get("success")) {
                    throw new ServiceException((String) memberRet.get("rows"));
                }
                List<Member> members = (List<Member>) memberRet1.get("rows");
                if (members.size() > 0) {
                    member = JSON.parseObject(JSON.toJSONString(members.get(0)), Member.class);
                } else {
                    throw new ServiceException("ORDER-092");
                }
            }
        }
        //订单的交易包括订单行的信息
        SaleOrderItem queryLine = new SaleOrderItem();
        Long orderId = saleOrder.getId();
        queryLine.setHeadId(orderId);
        List<SaleOrderItem> items = saleOrderItemService.queryByExamplePage(queryLine);
        // 准备参数
        List<Transaction> paramList = new ArrayList<>(items.size() + 1);
        // 订单头交易信息
        Transaction headParam = new Transaction();
        headParam.setMemberId(member.getId());
        headParam.setProgramId(member.getProgramId());
        headParam.setPartnerId(member.getPartnerId());
        headParam.setStatus("Submitted");
        headParam.setOrderId(orderId);
        headParam.setAmount(saleOrder.getOrderAmount());
        headParam.setOrderAttr("Whole Order");
        String transactionType = registerFlag ? "Accrual" : "Redemption";
        headParam.setTransactionType(transactionType);
        String transactionSubType = "PurchaseProduct";
        headParam.setOrderClass("Head");
        headParam.setTransactionSubType(transactionSubType);
        Long assocOrdId = registerFlag ? null : orderId;
        headParam.setAssocOrdId(assocOrdId);
        headParam.setFormId(formId);
        // 积分商城积分兑换订单 不生成头交易
        if (!"IntegralOrder".equals(saleOrder.getOrderType())) {
            headParam.setDataType("HeadData");
            paramList.add(headParam);
        }
        for (SaleOrderItem item : items) {
            // 订单行交易信息
            Transaction lineParam = new Transaction();
            lineParam.setMemberId(member.getId());
            lineParam.setProgramId(member.getProgramId());
            lineParam.setPartnerId(member.getPartnerId());
            lineParam.setStatus("Submitted");
            lineParam.setOrderId(orderId);
            lineParam.setOrderAttr("OrderItem");
            lineParam.setTransactionType(transactionType);
            lineParam.setTransactionSubType(transactionSubType);
            lineParam.setAssocOrdId(assocOrdId);
            lineParam.setDataType("LineData");
            lineParam.setNewMemberFlag("N");
            lineParam.setProdCode(item.getProdCode());
            lineParam.setProductId(item.getProdId());
            lineParam.setOrderClass("Item");
            lineParam.setFormId(formId);
            // 积分兑换商品交易特殊字段
            if (StringUtils.equals("IntegralOrder",saleOrder.getOrderType())) {
                Product product1 = new Product();
                product1.setId(item.getProdId());
                product1.setPriceListId(UserUtil.getUser().getPriceListId());
                product1 = productMapper.queryById(product1);
                lineParam.setTransactionSubType("PointExchange");
                lineParam.setTransactionType("Redemption");
                // 产品积分-交易积分
                lineParam.setPoints(product1.getPoint());
                // 更新积分到订单行上
                item.setBasePoints(product1.getPoint());
                saleOrderItemService.update(item);
            } else {
                // 设置交易金额
                lineParam.setAmount(item.getQty() * item.getPromotionPrice());
            }
            paramList.add(lineParam);
        }
        LCLogger.info().withMessageKey("createAndExecuteTxn")
                .withMessage("订单createTxn【createAndExecuteTxn】入参：" + JSON.toJSONString(paramList)).flush();
        Map<String, Object> txnResult = transactionClient.createAndExecuteTxn(paramList);
        LCLogger.info().withMessageKey("createAndExecuteTxn")
                .withMessage("订单createTxn【createAndExecuteTxn】返参：" + txnResult).flush();

    }

    /**
     * 根据录入结果生成相应订单
     *
     * @author 姚江漪
     * @date 2019/08/17 15:03
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void genInteractionOrder(JSONObject jsonObject) throws Exception {
        // 校验传入产品物流码和品牌 以及相关订单数据
        checkOrderData(jsonObject);
        // 根据判断生成一个订单
        SaleOrder saleOrder = checkSalesOrder(jsonObject);
        // 通过传入产品行生成订单行
        List<Product> productList = (List<Product>) jsonObject.get("products");
        for (int i = 0; i < productList.size(); i++) {
            Product product = JSON.parseObject(JSON.toJSONString(productList.get(i)), Product.class);
            SaleOrderItem saleOrderItem = new SaleOrderItem();
            saleOrderItem.setHeadId(saleOrder.getId());
            saleOrderItem.setProdId(product.getId());
            saleOrderItem.setQty(product.getCount());
            saleOrderItem.setProdUnit(product.getProdUnit());
            saleOrderItem.setItemType("Common Item");
            saleOrderItem.setManualPrice(0.00);
            saleOrderItem.setPromotionPrice(0.00);
            saleOrderItemService.insert(saleOrderItem);
        }

        // 关联附件
        List<Attachment> attachmentList = (List<Attachment>) jsonObject.get("attachments");
        for (int j = 0; j < attachmentList.size(); j++) {
            Attachment attachment = JSON.parseObject(JSON.toJSONString(attachmentList.get(j)), Attachment.class);
            attachment.setHeadId(saleOrder.getId());
            attachmentService.attachmentHeadIdUpdate(attachment);
        }
    }

    /**
     * 校验传入产品物流码和品牌 以及相关订单数据
     *
     * @author 姚江漪
     * @date 2019/08/29 09:57
     */
    public void checkOrderData(JSONObject jsonObject) throws Exception {
        if (StringUtils.isBlank(jsonObject.getString("consumerName")) || StringUtils.isBlank(jsonObject.getString("mobilePhone"))) {
            throw new BasicServiceException("请输入必输字段！");
        }

        List<Product> productList = (List<Product>) jsonObject.get("products");
        if (productList == null || productList.size() <= 0) {
            throw new BasicServiceException("产品不允许为空！");
        }

        List<String> productCodeList = new ArrayList<>();
        for (int i = 0; i < productList.size(); i++) {
            Product product = JSON.parseObject(JSON.toJSONString(productList.get(i)), Product.class);
            if (product.getId() == null || product.getCount() == null || product.getCount() == 0) {
                throw new BasicServiceException("不存在该产品或产品数量为不大于0！");
            }
            productCodeList.add(product.getProdBarcode());
        }
        HashSet<String> set = new HashSet<>(productCodeList);
        Boolean repeatFlag = set.size() == productCodeList.size();
        if (!repeatFlag) {
            throw new BasicServiceException("提交的物流码重复添加，请换个产品物流码重试");
        }
        List<Attachment> attachmentList = (List<Attachment>) jsonObject.get("attachments");
        if (attachmentList == null || attachmentList.size() <= 0) {
            throw new BasicServiceException("附件不允许为空！");
        }
    }

    /**
     * 判断是否需要清空订单
     *
     * @author 姚江漪
     * @date 2019/08/17 15:03
     */
    public SaleOrder checkSalesOrder(JSONObject jsonObject) throws Exception {
        Long orderId = jsonObject.getLong("orderId");
        SaleOrder saleOrder = new SaleOrder();
        if (orderId == null) {
            String mobilePhone = jsonObject.getString("mobilePhone");
            Long interactionId = jsonObject.getLong("interactionId");
            SaleOrder saleOrderQuery = (SaleOrder) QueryParamUtil.addQpsFilter(SaleOrder.class,
                    new Filter("customMobilePhone", mobilePhone),
                    new Filter("interactionId", String.valueOf(interactionId)));
            List<SaleOrder> saleOrderList = saleOrderMapper.queryByExamplePage(saleOrderQuery);
            if (saleOrderList.size() <= 0) {
                saleOrder.setCustomConsignee(jsonObject.getString("consumerName"));
                saleOrder.setCustomMobilePhone(jsonObject.getString("mobilePhone"));
                saleOrder.setOrderDate(DateUtil.dateToStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
                saleOrder.setStatus("New");
                saleOrder.setOrderType("SalesOrder");
                saleOrder.setProvince(jsonObject.getString("consigneeProvince"));
                saleOrder.setCity(jsonObject.getString("consigneeCity"));
                saleOrder.setDistrict(jsonObject.getString("consigneeDistrict"));
                saleOrder.setOrderChildType("ConsumerOrder");
                saleOrder.setOrderKind("TerminalOrder");
                saleOrder.setInteractionId(interactionId);
                saleOrder.setAcctId(jsonObject.getLong("acctId"));
                saleOrder.setOrderAmount(0.00);
                saleOrder.setSourceFrom(" OrderRegistration");

                // 获取互动上相关字段
                JSONObject queryJSONObject = new JSONObject();
                queryJSONObject.put("id", interactionId);
                Map<String, Object> mapResult = new HashMap<>();
                mapResult = interactionClient.queryById(queryJSONObject);
                Boolean successFlg = (Boolean) mapResult.get("success");
                if (!successFlg) {
                    throw new BasicServiceException(mapResult.get("result").toString());
                }
                JSONObject interaction = JSON.parseObject(JSON.toJSONString(mapResult.get("result")));
                if (interaction.isEmpty()) {
                    throw new BasicServiceException("互动编码：" + interactionId + "不存在，请联系管理员查看！");
                }
                saleOrder.setMcActId(interaction.getLong("marketActivityId"));
                saleOrder.setCompanyId(interaction.getLong("companyId"));

                this.insert(saleOrder);
            } else {
                saleOrder = this.queryById(saleOrderList.get(0));
                deleteByOrderId(saleOrderList.get(0).getId());
            }
        } else {
            saleOrder = this.queryById(orderId);
            deleteByOrderId(orderId);
        }
        return saleOrder;
    }

    /**
     * 已有订单需要清除旧的订单行
     *
     * @author 姚江漪
     * @date 2019/08/17 15:03
     */
    public void deleteByOrderId(Long orderId) throws Exception {
        // 删除旧的订单行 旧的物流行
        SaleOrderItem itemQuery = (SaleOrderItem) QueryParamUtil.addQpsFilter(SaleOrderItem.class,
                new Filter("headId", String.valueOf(orderId)));
        List<SaleOrderItem> saleOrderItems = saleOrderItemService.queryByExamplePage(itemQuery);
        if (!CollectionUtils.isEmpty(saleOrderItems)) {
            for (SaleOrderItem item : saleOrderItems) {
                saleOrderItemService.deleteById(item);
            }
        }
        // 删除旧的附件关联关系
        Attachment attachmentQuery = new Attachment();
        attachmentQuery.setHeadId(orderId);
        attachmentService.deleteByHeadId(attachmentQuery);
//        List<Attachment> attachmentList = attachmentService.queryAttachmentByHeadId(attachmentQuery);
//        for (Attachment attachment : attachmentList) {
//            attachment.setHeadId("headId");
//            attachmentService.attachmentHeadIdUpdate(attachment);
//        }
    }

    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void createRewardOrder(SaleOrder entity) {
        // 添加奖励订单头记录
        try {
            this.insert(entity);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new BasicServiceException(e.getMessage());
        }
        // 根据奖励id获取奖励信息
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", entity.getCouponsId());
        Map<String, Object> couponsMap = couponsClient.queryById(jsonObject);
        Boolean success = (Boolean) couponsMap.get("success");
        if (!success) {
            throw new BasicServiceException("查询奖励信息失败");
        }
        // 将结果转换成model
        Coupons coupons = JSON.parseObject(JSON.toJSONString(couponsMap.get("result")), Coupons.class);
        // 根据奖励订单的奖励id创建订单行记录
        SaleOrderItem rewardOrderItem = new SaleOrderItem();
        // 设置订单头id
        rewardOrderItem.setHeadId(entity.getId());
        // 根据奖励中的产品id查询产品信息
        rewardOrderItem.setProdId(coupons.getProdId());
        rewardOrderItem.setProdNum("1");
        // 根据产品id获取产品单位信息，如果产品或产品单位为空，默认赋值为“个”
        Product product = null;
        try {
            product = productService.queryById(coupons.getProdId());
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        if (null == product || StringUtils.isBlank(product.getProdUnit())) {
            rewardOrderItem.setProdUnit("个");
        } else {
            rewardOrderItem.setProdUnit(product.getProdUnit());
        }
        rewardOrderItem.setQty(new Double(1));
        rewardOrderItem.setAmount(new Double(0));
        rewardOrderItem.setPromotionPrice(new Double(0));
        // 添加奖励订单行记录
        try {
            saleOrderItemService.insert(rewardOrderItem);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new BasicServiceException(e.getMessage());
        }

        // 创建物流记录
        LogCode logCode = new LogCode();
        logCode.setOrderLineId(rewardOrderItem.getId());
        logCode.setLogTime(DateUtil.dateToStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
        // 物流记录默认状态为已接单
        String statusLov = null;
        try {
            statusLov = LovUtil.getLovValue("ORDER_LOG_STATUS", "已接单");
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        if (StringUtils.isBlank(statusLov)) {
            statusLov = "received";
        }
        logCode.setLogStatus(statusLov);
        // 订单状态为“已接单”，物流说明默认为“等待发货中”
        logCode.setLogExplain("等待发货中");
        // 添加物流记录
        try {
            logCodeService.insert(logCode);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new BasicServiceException(e.getMessage());
        }
    }
}
